/// <summary> /// Validates the group member does not already exist based on GroupId, GroupRoleId, and PersonId /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="groupType">Type of the group.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ValidateGroupMemberDuplicateMember(RockContext rockContext, GroupTypeCache groupType, out string errorMessage) { errorMessage = string.Empty; var groupService = new GroupService(rockContext); var group = this.Group ?? groupService.Queryable().AsNoTracking().Where(g => g.Id == this.GroupId).FirstOrDefault(); if (!groupService.AllowsDuplicateMembers(group)) { var groupMember = new GroupMemberService(rockContext).GetByGroupIdAndPersonIdAndGroupRoleId(this.GroupId, this.PersonId, this.GroupRoleId); if (groupMember != null && groupMember.Id != this.Id) { var person = this.Person ?? new PersonService(rockContext).Get(this.PersonId); var groupRole = groupType.Roles.First(a => a.Id == this.GroupRoleId); errorMessage = string.Format( "{0} already belongs to the {1} role for this {2}, and cannot be added again with the same role", person, groupRole.Name.ToLower(), groupType.GroupTerm.ToLower()); return(false); } } return(true); }
private void BindGrid() { string type = PageParameter( "SearchType" ); string term = PageParameter( "SearchTerm" ); var groupService = new GroupService( new RockContext() ); var groups = new List<Group>(); if ( !string.IsNullOrWhiteSpace( type ) && !string.IsNullOrWhiteSpace( term ) ) { switch ( type.ToLower() ) { case "name": { groups = groupService.Queryable() .Where( g => g.GroupType.ShowInNavigation && g.Name.Contains( term ) ) .OrderBy( g => g.Order ) .ThenBy( g => g.Name ) .ToList(); break; } } } if ( groups.Count == 1 ) { Response.Redirect( string.Format( "~/Group/{0}", groups[0].Id ), false ); Context.ApplicationInstance.CompleteRequest(); } else { gGroups.EntityTypeId = EntityTypeCache.Read<Group>().Id; gGroups.DataSource = groups .Select( g => new { g.Id, GroupType = g.GroupType.Name, Structure = ParentStructure( g ), MemberCount = g.Members.Count() } ) .ToList(); gGroups.DataBind(); } }
/// <summary> /// Loads the drop downs. /// </summary> private void LoadDropDowns() { // Controls on Main Campaign Panel GroupService groupService = new GroupService(); List<Group> groups = groupService.Queryable().Where( a => a.GroupType.Guid.Equals( Rock.SystemGuid.GroupType.GROUPTYPE_EVENTATTENDEES ) ).OrderBy( a => a.Name ).ToList(); groups.Insert( 0, new Group { Id = None.Id, Name = None.Text } ); ddlEventGroup.DataSource = groups; ddlEventGroup.DataBind(); PersonService personService = new PersonService(); List<Person> persons = personService.Queryable().OrderBy( a => a.NickName ).ThenBy( a => a.LastName ).ToList(); persons.Insert( 0, new Person { Id = None.Id, GivenName = None.Text } ); ddlContactPerson.DataSource = persons; ddlContactPerson.DataBind(); CampusService campusService = new CampusService(); cpCampuses.Campuses = campusService.Queryable().OrderBy( a => a.Name ).ToList(); ; // Controls on Ad Child Panel MarketingCampaignAdTypeService marketingCampaignAdTypeService = new MarketingCampaignAdTypeService(); var adtypes = marketingCampaignAdTypeService.Queryable().OrderBy( a => a.Name ).ToList(); ddlMarketingCampaignAdType.DataSource = adtypes; ddlMarketingCampaignAdType.DataBind(); }
//// //// Group Methods /// <summary> /// Displays the view group using a lava template /// </summary> private void DisplayViewGroup() { if ( _groupId > 0 ) { RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); bool enableDebug = GetAttributeValue( "EnableDebug" ).AsBoolean(); var qry = groupService .Queryable( "GroupLocations,Members,Members.Person,Members.Person.PhoneNumbers,GroupType" ) .Where( g => g.Id == _groupId ); if ( !enableDebug ) { qry = qry.AsNoTracking(); } var group = qry.FirstOrDefault(); // order group members by name if ( group != null ) { group.Members = group.Members.OrderBy( m => m.Person.LastName ).ThenBy( m => m.Person.FirstName ).ToList(); } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); mergeFields.Add( "Group", group ); // add linked pages Dictionary<string, object> linkedPages = new Dictionary<string, object>(); linkedPages.Add( "PersonDetailPage", LinkedPageRoute( "PersonDetailPage" ) ); linkedPages.Add( "RosterPage", LinkedPageRoute( "RosterPage" ) ); linkedPages.Add( "AttendancePage", LinkedPageRoute( "AttendancePage" ) ); linkedPages.Add( "CommunicationPage", LinkedPageRoute( "CommunicationPage" ) ); mergeFields.Add( "LinkedPages", linkedPages ); // add collection of allowed security actions Dictionary<string, object> securityActions = new Dictionary<string, object>(); securityActions.Add( "View", group != null && group.IsAuthorized( Authorization.VIEW, CurrentPerson ) ); securityActions.Add( "Edit", group != null && group.IsAuthorized( Authorization.EDIT, CurrentPerson ) ); securityActions.Add( "Administrate", group != null && group.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ) ); mergeFields.Add( "AllowedActions", securityActions ); Dictionary<string, object> currentPageProperties = new Dictionary<string, object>(); currentPageProperties.Add( "Id", RockPage.PageId ); currentPageProperties.Add( "Path", Request.Path ); mergeFields.Add( "CurrentPage", currentPageProperties ); string template = GetAttributeValue( "LavaTemplate" ); // show debug info if ( enableDebug && IsUserAuthorized( Authorization.EDIT ) ) { string postbackCommands = @"<h5>Available Postback Commands</h5> <ul> <li><strong>EditGroup:</strong> Shows a panel for modifing group info. Expects a group id. <code>{{ Group.Id | Postback:'EditGroup' }}</code></li> <li><strong>AddGroupMember:</strong> Shows a panel for adding group info. Does not require input. <code>{{ '' | Postback:'AddGroupMember' }}</code></li> <li><strong>EditGroupMember:</strong> Shows a panel for modifing group info. Expects a group member id. <code>{{ member.Id | Postback:'EditGroupMember' }}</code></li> <li><strong>DeleteGroupMember:</strong> Deletes a group member. Expects a group member id. <code>{{ member.Id | Postback:'DeleteGroupMember' }}</code></li> <li><strong>SendCommunication:</strong> Sends a communication to all group members on behalf of the Current User. This will redirect them to the communication page where they can author their email. <code>{{ '' | Postback:'SendCommunication' }}</code></li> </ul>"; lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo( null, string.Empty, postbackCommands ); } lContent.Text = template.ResolveMergeFields( mergeFields ).ResolveClientIds( upnlContent.ClientID ); } else { lContent.Text = "<div class='alert alert-warning'>No group was available from the querystring.</div>"; } }
/// <summary> /// Loads the drop downs. /// </summary> private void LoadDropDowns() { // Controls on Main Campaign Panel GroupService groupService = new GroupService( new RockContext() ); List<Group> groups = groupService.Queryable().Where( a => a.GroupType.Guid.Equals( new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_EVENTATTENDEES ) ) ).OrderBy( a => a.Name ).ToList(); groups.Insert( 0, new Group { Id = None.Id, Name = None.Text } ); ddlEventGroup.DataSource = groups; ddlEventGroup.DataBind(); }
/// <summary> /// Binds the grid. /// </summary> private void ShowResults() { // Get the group types that we're interested in Guid? groupTypeGuid = GetAttributeValue( "GroupType" ).AsGuidOrNull(); if ( !groupTypeGuid.HasValue ) { ShowError( "A valid Group Type is required." ); return; } gGroups.Columns[1].Visible = GetAttributeValue( "ShowDescription" ).AsBoolean(); gGroups.Columns[2].Visible = GetAttributeValue( "ShowSchedule" ).AsBoolean(); gGroups.Columns[3].Visible = GetAttributeValue( "ShowCount" ).AsBoolean(); gGroups.Columns[4].Visible = GetAttributeValue( "ShowAge" ).AsBoolean(); bool showProximity = GetAttributeValue( "ShowProximity" ).AsBoolean(); gGroups.Columns[5].Visible = showProximity; // Distance // Get query of groups of the selected group type var rockContext = new RockContext(); var groupService = new GroupService( rockContext ); var groupQry = groupService .Queryable( "GroupLocations.Location" ) .Where( g => g.IsActive && g.GroupType.Guid.Equals( groupTypeGuid.Value ) && g.IsPublic ); var groupParameterExpression = groupService.ParameterExpression; var schedulePropertyExpression = Expression.Property( groupParameterExpression, "Schedule" ); var dowFilterControl = phFilterControls.FindControl( "filter_dow" ); if ( dowFilterControl != null ) { var field = FieldTypeCache.Read( Rock.SystemGuid.FieldType.DAY_OF_WEEK ).Field; var filterValues = field.GetFilterValues( dowFilterControl, null, Rock.Reporting.FilterMode.SimpleFilter ); var expression = field.PropertyFilterExpression( null, filterValues, schedulePropertyExpression, "WeeklyDayOfWeek", typeof( DayOfWeek? ) ); groupQry = groupQry.Where( groupParameterExpression, expression, null ); } var timeFilterControl = phFilterControls.FindControl( "filter_time" ); if ( timeFilterControl != null ) { var field = FieldTypeCache.Read( Rock.SystemGuid.FieldType.TIME ).Field; var filterValues = field.GetFilterValues( timeFilterControl, null, Rock.Reporting.FilterMode.SimpleFilter ); var expression = field.PropertyFilterExpression( null, filterValues, schedulePropertyExpression, "WeeklyTimeOfDay", typeof( TimeSpan? ) ); groupQry = groupQry.Where( groupParameterExpression, expression, null ); } // Filter query by any configured attribute filters if ( AttributeFilters != null && AttributeFilters.Any() ) { var attributeValueService = new AttributeValueService( rockContext ); var parameterExpression = attributeValueService.ParameterExpression; foreach ( var attribute in AttributeFilters ) { var filterControl = phFilterControls.FindControl( "filter_" + attribute.Id.ToString() ); if ( filterControl != null ) { var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues, Rock.Reporting.FilterMode.SimpleFilter ); var expression = attribute.FieldType.Field.AttributeFilterExpression( attribute.QualifierValues, filterValues, parameterExpression ); if ( expression != null ) { var attributeValues = attributeValueService .Queryable() .Where( v => v.Attribute.Id == attribute.Id ); attributeValues = attributeValues.Where( parameterExpression, expression, null ); groupQry = groupQry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) ); } } } } List<GroupLocation> fences = null; List<Group> groups = null; // Run query to get list of matching groups SortProperty sortProperty = gGroups.SortProperty; if ( sortProperty != null ) { groups = groupQry.Sort( sortProperty ).ToList(); } else { groups = groupQry.OrderBy( g => g.Name ).ToList(); } int? fenceGroupTypeId = GetGroupTypeId( GetAttributeValue( "GeofencedGroupType" ).AsGuidOrNull() ); bool showMap = GetAttributeValue( "ShowMap" ).AsBoolean(); bool showFences = showMap && GetAttributeValue( "ShowFence" ).AsBoolean(); var distances = new Dictionary<int, double>(); // If we care where these groups are located... if ( fenceGroupTypeId.HasValue || showMap || showProximity ) { // Get the location for the address entered Location personLocation = null; if ( fenceGroupTypeId.HasValue || showProximity ) { personLocation = new LocationService( rockContext ) .Get( acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country ); } // If showing a map, and person's location was found, save a mapitem for this location FinderMapItem personMapItem = null; if ( showMap && personLocation != null && personLocation.GeoPoint != null ) { var infoWindow = string.Format( @" <div style='width:250px'> <div class='clearfix'> <strong>Your Location</strong> <br/>{0} </div> </div> ", personLocation.FormattedHtmlAddress ); personMapItem = new FinderMapItem( personLocation ); personMapItem.Name = "Your Location"; personMapItem.InfoWindow = HttpUtility.HtmlEncode( infoWindow.Replace( Environment.NewLine, string.Empty ).Replace( "\n", string.Empty ).Replace( "\t", string.Empty ) ); } // Get the locations, and optionally calculate the distance for each of the groups var groupLocations = new List<GroupLocation>(); foreach ( var group in groups ) { foreach ( var groupLocation in group.GroupLocations .Where( gl => gl.Location.GeoPoint != null ) ) { groupLocations.Add( groupLocation ); if ( showProximity && personLocation != null && personLocation.GeoPoint != null ) { double meters = groupLocation.Location.GeoPoint.Distance( personLocation.GeoPoint ) ?? 0.0D; double miles = meters * Location.MilesPerMeter; // If this group already has a distance calculated, see if this location is closer and if so, use it instead if ( distances.ContainsKey( group.Id ) ) { if ( distances[group.Id] < miles ) { distances[group.Id] = miles; } } else { distances.Add( group.Id, miles ); } } } } // If groups should be limited by a geofence var fenceMapItems = new List<MapItem>(); if ( fenceGroupTypeId.HasValue ) { fences = new List<GroupLocation>(); if ( personLocation != null && personLocation.GeoPoint != null ) { fences = new GroupLocationService( rockContext ) .Queryable( "Group,Location" ) .Where( gl => gl.Group.GroupTypeId == fenceGroupTypeId && gl.Location.GeoFence != null && personLocation.GeoPoint.Intersects( gl.Location.GeoFence ) ) .ToList(); } // Limit the group locations to only those locations inside one of the fences groupLocations = groupLocations .Where( gl => fences.Any( f => gl.Location.GeoPoint.Intersects( f.Location.GeoFence ) ) ) .ToList(); // Limit the groups to the those that still contain a valid location groups = groups .Where( g => groupLocations.Any( gl => gl.GroupId == g.Id ) ) .ToList(); // If the map and fences should be displayed, create a map item for each fence if ( showMap && showFences ) { foreach ( var fence in fences ) { var mapItem = new FinderMapItem( fence.Location ); mapItem.EntityTypeId = EntityTypeCache.Read( "Rock.Model.Group" ).Id; mapItem.EntityId = fence.GroupId; mapItem.Name = fence.Group.Name; fenceMapItems.Add( mapItem ); } } } // if not sorting by ColumnClick and SortByDistance, then sort the groups by distance if ( gGroups.SortProperty == null && GetAttributeValue( "SortByDistance" ).AsBoolean() ) { // only show groups with a known location, and sort those by distance groups = groups.Where( a => distances.Select( b => b.Key ).Contains( a.Id ) ).ToList(); groups = groups.OrderBy( a => distances[a.Id] ).ThenBy( a => a.Name ).ToList(); } // if limiting by PageSize, limit to the top X groups int? pageSize = ddlPageSize.SelectedValue.AsIntegerOrNull(); if ( pageSize.HasValue && pageSize > 0 ) { groups = groups.Take( pageSize.Value ).ToList(); } // If a map is to be shown if ( showMap && groups.Any() ) { Template template = Template.Parse( GetAttributeValue( "MapInfo" ) ); bool showDebug = UserCanEdit && GetAttributeValue( "MapInfoDebug" ).AsBoolean(); lMapInfoDebug.Visible = showDebug; // Add mapitems for all the remaining valid group locations var groupMapItems = new List<MapItem>(); foreach ( var gl in groupLocations ) { var group = groups.Where( g => g.Id == gl.GroupId ).FirstOrDefault(); if ( group != null ) { // Resolve info window lava template var linkedPageParams = new Dictionary<string, string> { { "GroupId", group.Id.ToString() } }; var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Group", gl.Group ); mergeFields.Add( "Location", gl.Location ); Dictionary<string, object> linkedPages = new Dictionary<string, object>(); linkedPages.Add( "GroupDetailPage", LinkedPageRoute( "GroupDetailPage" ) ); if ( _targetPersonGuid != Guid.Empty ) { linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", _urlParms ) ); } else { linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", null ) ); } mergeFields.Add( "LinkedPages", linkedPages ); // add collection of allowed security actions Dictionary<string, object> securityActions = new Dictionary<string, object>(); securityActions.Add( "View", group.IsAuthorized( Authorization.VIEW, CurrentPerson ) ); securityActions.Add( "Edit", group.IsAuthorized( Authorization.EDIT, CurrentPerson ) ); securityActions.Add( "Administrate", group.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ) ); mergeFields.Add( "AllowedActions", securityActions ); string infoWindow = template.Render( Hash.FromDictionary( mergeFields ) ); if ( showDebug ) { lMapInfoDebug.Text = mergeFields.lavaDebugInfo( null, "<span class='label label-info'>Lava used for the map window.</span>", "" ); showDebug = false; } // Add a map item for group var mapItem = new FinderMapItem( gl.Location ); mapItem.EntityTypeId = EntityTypeCache.Read( "Rock.Model.Group" ).Id; mapItem.EntityId = group.Id; mapItem.Name = group.Name; mapItem.InfoWindow = HttpUtility.HtmlEncode( infoWindow.Replace( Environment.NewLine, string.Empty ).Replace( "\n", string.Empty ).Replace( "\t", string.Empty ) ); groupMapItems.Add( mapItem ); } } // Show the map Map( personMapItem, fenceMapItems, groupMapItems ); pnlMap.Visible = true; } else { pnlMap.Visible = false; } } else { pnlMap.Visible = false; } // Should a lava output be displayed if ( GetAttributeValue( "ShowLavaOutput" ).AsBoolean() ) { string template = GetAttributeValue( "LavaOutput" ); var mergeFields = new Dictionary<string, object>(); if ( fences != null ) { mergeFields.Add( "Fences", fences.Select( f => f.Group ).ToList() ); } else { mergeFields.Add( "Fences", new Dictionary<string, object>() ); } mergeFields.Add( "Groups", groups ); Dictionary<string, object> linkedPages = new Dictionary<string, object>(); linkedPages.Add( "GroupDetailPage", LinkedPageUrl( "GroupDetailPage", null ) ); if ( _targetPersonGuid != Guid.Empty ) { linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", _urlParms ) ); } else { linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", null ) ); } mergeFields.Add( "LinkedPages", linkedPages ); lLavaOverview.Text = template.ResolveMergeFields( mergeFields ); bool showDebug = UserCanEdit && GetAttributeValue( "LavaOutputDebug" ).AsBoolean(); lLavaOutputDebug.Visible = showDebug; if ( showDebug ) { lLavaOutputDebug.Text = mergeFields.lavaDebugInfo( null, "<span class='label label-info'>Lava used for the summary info.</span>" ); } pnlLavaOutput.Visible = true; } else { pnlLavaOutput.Visible = false; } // Should a grid be displayed if ( GetAttributeValue( "ShowGrid" ).AsBoolean() ) { pnlGrid.Visible = true; // Save the groups into the grid's object list since it is not being bound to actual group objects gGroups.ObjectList = new Dictionary<string, object>(); groups.ForEach( g => gGroups.ObjectList.Add( g.Id.ToString(), g ) ); // Bind the grid gGroups.DataSource = groups.Select( g => { var qryMembers = new GroupMemberService( rockContext ).Queryable().Where( a => a.GroupId == g.Id ); var groupType = GroupTypeCache.Read( g.GroupTypeId ); return new { Id = g.Id, Name = g.Name, GroupTypeName = groupType.Name, GroupOrder = g.Order, GroupTypeOrder = groupType.Order, Description = g.Description, IsSystem = g.IsSystem, IsActive = g.IsActive, GroupRole = string.Empty, DateAdded = DateTime.MinValue, Schedule = g.Schedule, MemberCount = qryMembers.Count(), AverageAge = Math.Round( qryMembers.Select( m => m.Person.BirthDate ).ToList().Select( a => Person.GetAge( a ) ).Average() ?? 0.0D ), Distance = distances.Where( d => d.Key == g.Id ) .Select( d => d.Value ).FirstOrDefault() }; } ).ToList(); gGroups.DataBind(); } else { pnlGrid.Visible = false; } // Show the results pnlResults.Visible = true; }
private void Map() { string mapStylingFormat = @" <style> #map_wrapper {{ height: {0}px; }} #map_canvas {{ width: 100%; height: 100%; border-radius: 8px; }} </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; if ( GetAttributeValue( "ShowMapInfoWindow" ).AsBoolean() ) { template = Template.Parse( GetAttributeValue( "InfoWindowContents" ).Trim() ); } else { template = Template.Parse( string.Empty ); } 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.Read( 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.Read( 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, 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 ); } // enable showing debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = dynamicGroups.Take( 5 ).lavaDebugInfo(); } else { lDebug.Visible = false; lDebug.Text = string.Empty; } foreach ( var group in dynamicGroups ) { if ( group.GroupLocation != null && group.GroupLocation.Latitude != null ) { groupsMapped++; var groupDict = group as IDictionary<string, object>; string infoWindow = template.Render( Hash.FromDictionary( groupDict ) ).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.Read( 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 = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor, new google.maps.Size(21, 34), new google.maps.Point(0,0), new google.maps.Point(10, 34)); var pinShadow = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_shadow', new google.maps.Size(40, 37), new google.maps.Point(0, 0), new google.maps.Point(12, 35)); 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, shadow: pinShadow }}); // 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>"; } } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { Group group; bool wasSecurityRole = false; bool triggersUpdated = false; RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); GroupLocationService groupLocationService = new GroupLocationService( rockContext ); GroupRequirementService groupRequirementService = new GroupRequirementService( rockContext ); GroupMemberWorkflowTriggerService groupMemberWorkflowTriggerService = new GroupMemberWorkflowTriggerService( rockContext ); ScheduleService scheduleService = new ScheduleService( rockContext ); AttributeService attributeService = new AttributeService( rockContext ); AttributeQualifierService attributeQualifierService = new AttributeQualifierService( rockContext ); CategoryService categoryService = new CategoryService( rockContext ); var roleGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid() ); int roleGroupTypeId = roleGroupType != null ? roleGroupType.Id : int.MinValue; if ( CurrentGroupTypeId == 0 ) { ddlGroupType.ShowErrorMessage( Rock.Constants.WarningMessage.CannotBeBlank( GroupType.FriendlyTypeName ) ); return; } int groupId = hfGroupId.Value.AsInteger(); if ( groupId == 0 ) { group = new Group(); group.IsSystem = false; group.Name = string.Empty; } else { group = groupService.Queryable( "Schedule,GroupLocations.Schedules" ).Where( g => g.Id == groupId ).FirstOrDefault(); wasSecurityRole = group.IsActive && ( group.IsSecurityRole || group.GroupTypeId == roleGroupTypeId ); // remove any locations that removed in the UI var selectedLocations = GroupLocationsState.Select( l => l.Guid ); foreach ( var groupLocation in group.GroupLocations.Where( l => !selectedLocations.Contains( l.Guid ) ).ToList() ) { group.GroupLocations.Remove( groupLocation ); groupLocationService.Delete( groupLocation ); } // remove any group requirements that removed in the UI var selectedGroupRequirements = GroupRequirementsState.Select( a => a.Guid ); foreach ( var groupRequirement in group.GroupRequirements.Where( a => !selectedGroupRequirements.Contains( a.Guid ) ).ToList() ) { group.GroupRequirements.Remove( groupRequirement ); groupRequirementService.Delete( groupRequirement ); } // Remove any triggers that were removed in the UI var selectedTriggerGuids = MemberWorkflowTriggersState.Select( r => r.Guid ); foreach ( var trigger in group.GroupMemberWorkflowTriggers.Where( r => !selectedTriggerGuids.Contains( r.Guid ) ).ToList() ) { group.GroupMemberWorkflowTriggers.Remove( trigger ); groupMemberWorkflowTriggerService.Delete( trigger ); triggersUpdated = true; } } // add/update any group requirements that were added or changed in the UI (we already removed the ones that were removed above) foreach ( var groupRequirementState in GroupRequirementsState ) { GroupRequirement groupRequirement = group.GroupRequirements.Where( a => a.Guid == groupRequirementState.Guid ).FirstOrDefault(); if ( groupRequirement == null ) { groupRequirement = new GroupRequirement(); group.GroupRequirements.Add( groupRequirement ); } groupRequirement.CopyPropertiesFrom( groupRequirementState ); } // add/update any group locations that were added or changed in the UI (we already removed the ones that were removed above) foreach ( var groupLocationState in GroupLocationsState ) { GroupLocation groupLocation = group.GroupLocations.Where( l => l.Guid == groupLocationState.Guid ).FirstOrDefault(); if ( groupLocation == null ) { groupLocation = new GroupLocation(); group.GroupLocations.Add( groupLocation ); } else { groupLocationState.Id = groupLocation.Id; groupLocationState.Guid = groupLocation.Guid; var selectedSchedules = groupLocationState.Schedules.Select( s => s.Guid ).ToList(); foreach ( var schedule in groupLocation.Schedules.Where( s => !selectedSchedules.Contains( s.Guid ) ).ToList() ) { groupLocation.Schedules.Remove( schedule ); } } groupLocation.CopyPropertiesFrom( groupLocationState ); var existingSchedules = groupLocation.Schedules.Select( s => s.Guid ).ToList(); foreach ( var scheduleState in groupLocationState.Schedules.Where( s => !existingSchedules.Contains( s.Guid ) ).ToList() ) { var schedule = scheduleService.Get( scheduleState.Guid ); if ( schedule != null ) { groupLocation.Schedules.Add( schedule ); } } } foreach ( var triggerState in MemberWorkflowTriggersState ) { GroupMemberWorkflowTrigger trigger = group.GroupMemberWorkflowTriggers.Where( r => r.Guid == triggerState.Guid ).FirstOrDefault(); if ( trigger == null ) { trigger = new GroupMemberWorkflowTrigger(); group.GroupMemberWorkflowTriggers.Add( trigger ); } else { triggerState.Id = trigger.Id; triggerState.Guid = trigger.Guid; } trigger.CopyPropertiesFrom( triggerState ); triggersUpdated = true; } group.Name = tbName.Text; group.Description = tbDescription.Text; group.CampusId = ddlCampus.SelectedValueAsInt(); group.GroupTypeId = CurrentGroupTypeId; group.ParentGroupId = gpParentGroup.SelectedValueAsInt(); group.GroupCapacity = nbGroupCapacity.Text.AsIntegerOrNull(); group.RequiredSignatureDocumentTemplateId = ddlSignatureDocumentTemplate.SelectedValueAsInt(); group.IsSecurityRole = cbIsSecurityRole.Checked; group.IsActive = cbIsActive.Checked; group.IsPublic = cbIsPublic.Checked; group.MustMeetRequirementsToAddMember = cbMembersMustMeetRequirementsOnAdd.Checked; // save sync settings group.SyncDataViewId = dvpSyncDataview.SelectedValue.AsIntegerOrNull(); group.WelcomeSystemEmailId = ddlWelcomeEmail.SelectedValue.AsIntegerOrNull(); group.ExitSystemEmailId = ddlExitEmail.SelectedValue.AsIntegerOrNull(); group.AddUserAccountsDuringSync = rbCreateLoginDuringSync.Checked; string iCalendarContent = string.Empty; // If unique schedule option was selected, but a schedule was not defined, set option to 'None' var scheduleType = rblScheduleSelect.SelectedValueAsEnum<ScheduleType>( ScheduleType.None ); if ( scheduleType == ScheduleType.Custom ) { iCalendarContent = sbSchedule.iCalendarContent; var calEvent = ScheduleICalHelper.GetCalenderEvent( iCalendarContent ); if ( calEvent == null || calEvent.DTStart == null ) { scheduleType = ScheduleType.None; } } if ( scheduleType == ScheduleType.Weekly ) { if ( !dowWeekly.SelectedDayOfWeek.HasValue ) { scheduleType = ScheduleType.None; } } int? oldScheduleId = hfUniqueScheduleId.Value.AsIntegerOrNull(); if ( scheduleType == ScheduleType.Custom || scheduleType == ScheduleType.Weekly ) { if ( !oldScheduleId.HasValue || group.Schedule == null ) { group.Schedule = new Schedule(); } if ( scheduleType == ScheduleType.Custom ) { group.Schedule.iCalendarContent = iCalendarContent; group.Schedule.WeeklyDayOfWeek = null; group.Schedule.WeeklyTimeOfDay = null; } else { group.Schedule.iCalendarContent = null; group.Schedule.WeeklyDayOfWeek = dowWeekly.SelectedDayOfWeek; group.Schedule.WeeklyTimeOfDay = timeWeekly.SelectedTime; } } else { // If group did have a unique schedule, delete that schedule if ( oldScheduleId.HasValue ) { var schedule = scheduleService.Get( oldScheduleId.Value ); if ( schedule != null && string.IsNullOrEmpty( schedule.Name ) ) { // Make sure this is the only group trying to use this schedule. if ( !groupService.Queryable().Where( g => g.ScheduleId == schedule.Id && g.Id != group.Id ).Any() ) { scheduleService.Delete( schedule ); } } } if ( scheduleType == ScheduleType.Named ) { group.ScheduleId = spSchedule.SelectedValueAsId(); } else { group.ScheduleId = null; } } if ( group.ParentGroupId == group.Id ) { gpParentGroup.ShowErrorMessage( "Group cannot be a Parent Group of itself." ); return; } group.LoadAttributes(); Rock.Attribute.Helper.GetEditValues( phGroupAttributes, group ); group.GroupType = new GroupTypeService( rockContext ).Get( group.GroupTypeId ); if ( group.ParentGroupId.HasValue ) { group.ParentGroup = groupService.Get( group.ParentGroupId.Value ); } // Check to see if group type is allowed as a child of new parent group. if ( group.ParentGroup != null ) { var allowedGroupTypeIds = GetAllowedGroupTypes( group.ParentGroup, rockContext ).Select( t => t.Id ).ToList(); if ( !allowedGroupTypeIds.Contains( group.GroupTypeId ) ) { var groupType = CurrentGroupTypeCache; nbInvalidParentGroup.Text = string.Format( "The '{0}' group does not allow child groups with a '{1}' group type.", group.ParentGroup.Name, groupType != null ? groupType.Name : string.Empty ); nbInvalidParentGroup.Visible = true; return; } } // Check to see if user is still allowed to edit with selected group type and parent group if ( !group.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { nbNotAllowedToEdit.Visible = true; return; } if ( !Page.IsValid ) { return; } // if the groupMember IsValid is false, and the UI controls didn't report any errors, it is probably because the custom rules of GroupMember didn't pass. // So, make sure a message is displayed in the validation summary cvGroup.IsValid = group.IsValid; if ( !cvGroup.IsValid ) { cvGroup.ErrorMessage = group.ValidationResults.Select( a => a.ErrorMessage ).ToList().AsDelimited( "<br />" ); return; } // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges() rockContext.WrapTransaction( () => { var adding = group.Id.Equals( 0 ); if ( adding ) { groupService.Add( group ); } rockContext.SaveChanges(); if ( adding ) { // add ADMINISTRATE to the person who added the group Rock.Security.Authorization.AllowPerson( group, Authorization.ADMINISTRATE, this.CurrentPerson, rockContext ); } group.SaveAttributeValues( rockContext ); /* Take care of Group Member Attributes */ var entityTypeId = EntityTypeCache.Read( typeof( GroupMember ) ).Id; string qualifierColumn = "GroupId"; string qualifierValue = group.Id.ToString(); // Get the existing attributes for this entity type and qualifier value var attributes = attributeService.Get( entityTypeId, qualifierColumn, qualifierValue ); // Delete any of those attributes that were removed in the UI var selectedAttributeGuids = GroupMemberAttributesState.Select( a => a.Guid ); foreach ( var attr in attributes.Where( a => !selectedAttributeGuids.Contains( a.Guid ) ) ) { Rock.Web.Cache.AttributeCache.Flush( attr.Id ); attributeService.Delete( attr ); } // Update the Attributes that were assigned in the UI foreach ( var attributeState in GroupMemberAttributesState ) { Rock.Attribute.Helper.SaveAttributeEdits( attributeState, entityTypeId, qualifierColumn, qualifierValue, rockContext ); } rockContext.SaveChanges(); if ( group.IsActive == false && cbInactivateChildGroups.Checked ) { var allActiveChildGroupsId = groupService.GetAllDescendents( group.Id ).Where( a => a.IsActive ).Select( a => a.Id ).ToList(); var allActiveChildGroups = groupService.GetByIds( allActiveChildGroupsId ); foreach ( var childGroup in allActiveChildGroups ) { if ( childGroup.IsActive ) { childGroup.IsActive = false; } } rockContext.SaveChanges(); } } ); bool isNowSecurityRole = group.IsActive && ( group.IsSecurityRole || group.GroupTypeId == roleGroupTypeId ); if ( group != null && wasSecurityRole ) { if ( !isNowSecurityRole ) { // if this group was a SecurityRole, but no longer is, flush Rock.Security.Role.Flush( group.Id ); Rock.Security.Authorization.Flush(); } } else { if ( isNowSecurityRole ) { // new security role, flush Rock.Security.Authorization.Flush(); } } AttributeCache.FlushEntityAttributes(); if ( triggersUpdated ) { GroupMemberWorkflowTriggerService.FlushCachedTriggers(); } var qryParams = new Dictionary<string, string>(); qryParams["GroupId"] = group.Id.ToString(); qryParams["ExpandedIds"] = PageParameter( "ExpandedIds" ); NavigateToPage( RockPage.Guid, qryParams ); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { Group group; bool wasSecurityRole = false; RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); GroupLocationService groupLocationService = new GroupLocationService( rockContext ); ScheduleService scheduleService = new ScheduleService( rockContext ); AttributeService attributeService = new AttributeService( rockContext ); AttributeQualifierService attributeQualifierService = new AttributeQualifierService( rockContext ); CategoryService categoryService = new CategoryService( rockContext ); if ( ( ddlGroupType.SelectedValueAsInt() ?? 0 ) == 0 ) { ddlGroupType.ShowErrorMessage( Rock.Constants.WarningMessage.CannotBeBlank( GroupType.FriendlyTypeName ) ); return; } int groupId = int.Parse( hfGroupId.Value ); if ( groupId == 0 ) { group = new Group(); group.IsSystem = false; group.Name = string.Empty; } else { group = groupService.Queryable( "Schedule,GroupLocations.Schedules" ).Where( g => g.Id == groupId ).FirstOrDefault(); wasSecurityRole = group.IsSecurityRole; var selectedLocations = GroupLocationsState.Select( l => l.Guid ); foreach ( var groupLocation in group.GroupLocations.Where( l => !selectedLocations.Contains( l.Guid ) ).ToList() ) { group.GroupLocations.Remove( groupLocation ); groupLocationService.Delete( groupLocation ); } } foreach ( var groupLocationState in GroupLocationsState ) { GroupLocation groupLocation = group.GroupLocations.Where( l => l.Guid == groupLocationState.Guid ).FirstOrDefault(); if ( groupLocation == null ) { groupLocation = new GroupLocation(); group.GroupLocations.Add( groupLocation ); } else { groupLocationState.Id = groupLocation.Id; groupLocationState.Guid = groupLocation.Guid; var selectedSchedules = groupLocationState.Schedules.Select( s => s.Guid ).ToList(); foreach( var schedule in groupLocation.Schedules.Where( s => !selectedSchedules.Contains( s.Guid)).ToList()) { groupLocation.Schedules.Remove( schedule ); } } groupLocation.CopyPropertiesFrom( groupLocationState ); var existingSchedules = groupLocation.Schedules.Select( s => s.Guid ).ToList(); foreach ( var scheduleState in groupLocationState.Schedules.Where( s => !existingSchedules.Contains( s.Guid )).ToList()) { var schedule = scheduleService.Get( scheduleState.Guid ); if ( schedule != null ) { groupLocation.Schedules.Add( schedule ); } } } group.Name = tbName.Text; group.Description = tbDescription.Text; group.CampusId = ddlCampus.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( ddlCampus.SelectedValue ); group.GroupTypeId = int.Parse( ddlGroupType.SelectedValue ); group.ParentGroupId = gpParentGroup.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( gpParentGroup.SelectedValue ); group.IsSecurityRole = cbIsSecurityRole.Checked; group.IsActive = cbIsActive.Checked; string iCalendarContent = string.Empty; // If unique schedule option was selected, but a schedule was not defined, set option to 'None' var scheduleType = rblScheduleSelect.SelectedValueAsEnum<ScheduleType>( ScheduleType.None ); if ( scheduleType == ScheduleType.Custom ) { iCalendarContent = sbSchedule.iCalendarContent; var calEvent = ScheduleICalHelper.GetCalenderEvent( iCalendarContent ); if ( calEvent == null || calEvent.DTStart == null ) { scheduleType = ScheduleType.None; } } if ( scheduleType == ScheduleType.Weekly ) { if ( !dowWeekly.SelectedDayOfWeek.HasValue ) { scheduleType = ScheduleType.None; } } int? oldScheduleId = hfUniqueScheduleId.Value.AsIntegerOrNull(); if ( scheduleType == ScheduleType.Custom || scheduleType == ScheduleType.Weekly ) { if ( !oldScheduleId.HasValue || group.Schedule == null ) { group.Schedule = new Schedule(); } if ( scheduleType == ScheduleType.Custom ) { group.Schedule.iCalendarContent = iCalendarContent; group.Schedule.WeeklyDayOfWeek = null; group.Schedule.WeeklyTimeOfDay = null; } else { group.Schedule.iCalendarContent = null; group.Schedule.WeeklyDayOfWeek = dowWeekly.SelectedDayOfWeek; group.Schedule.WeeklyTimeOfDay = timeWeekly.SelectedTime; } } else { // If group did have a unique schedule, delete that schedule if ( oldScheduleId.HasValue ) { var schedule = scheduleService.Get( oldScheduleId.Value ); if ( schedule != null && string.IsNullOrEmpty(schedule.Name) ) { scheduleService.Delete(schedule); } } if ( scheduleType == ScheduleType.Named ) { group.ScheduleId = spSchedule.SelectedValueAsId(); } else { group.ScheduleId = null; } } if ( group.ParentGroupId == group.Id ) { gpParentGroup.ShowErrorMessage( "Group cannot be a Parent Group of itself." ); return; } group.LoadAttributes(); Rock.Attribute.Helper.GetEditValues( phGroupAttributes, group ); group.GroupType = new GroupTypeService( rockContext ).Get( group.GroupTypeId ); if ( group.ParentGroupId.HasValue ) { group.ParentGroup = groupService.Get( group.ParentGroupId.Value ); } // Check to see if user is still allowed to edit with selected group type and parent group if ( !group.IsAuthorized( Authorization.EDIT, CurrentPerson )) { nbNotAllowedToEdit.Visible = true; return; } if ( !Page.IsValid ) { return; } if ( !group.IsValid ) { // Controls will render the error messages return; } // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges() rockContext.WrapTransaction( () => { var adding = group.Id.Equals( 0 ); if ( adding ) { groupService.Add( group ); } rockContext.SaveChanges(); if (adding) { // add ADMINISTRATE to the person who added the group Rock.Security.Authorization.AllowPerson( group, Authorization.ADMINISTRATE, this.CurrentPerson, rockContext ); } group.SaveAttributeValues( rockContext ); /* Take care of Group Member Attributes */ var entityTypeId = EntityTypeCache.Read( typeof( GroupMember ) ).Id; string qualifierColumn = "GroupId"; string qualifierValue = group.Id.ToString(); // Get the existing attributes for this entity type and qualifier value var attributes = attributeService.Get( entityTypeId, qualifierColumn, qualifierValue ); // Delete any of those attributes that were removed in the UI var selectedAttributeGuids = GroupMemberAttributesState.Select( a => a.Guid ); foreach ( var attr in attributes.Where( a => !selectedAttributeGuids.Contains( a.Guid ) ) ) { Rock.Web.Cache.AttributeCache.Flush( attr.Id ); attributeService.Delete( attr ); } // Update the Attributes that were assigned in the UI foreach ( var attributeState in GroupMemberAttributesState ) { Rock.Attribute.Helper.SaveAttributeEdits( attributeState, entityTypeId, qualifierColumn, qualifierValue, rockContext ); } rockContext.SaveChanges(); } ); if ( group != null && wasSecurityRole ) { if ( !group.IsSecurityRole ) { // if this group was a SecurityRole, but no longer is, flush Rock.Security.Role.Flush( group.Id ); Rock.Security.Authorization.Flush(); } } else { if ( group.IsSecurityRole ) { // new security role, flush Rock.Security.Authorization.Flush(); } } var qryParams = new Dictionary<string, string>(); qryParams["GroupId"] = group.Id.ToString(); qryParams["ExpandedIds"] = PageParameter( "ExpandedIds" ); NavigateToPage( RockPage.Guid, qryParams ); }
/// <summary> /// Loads the groups. /// </summary> private void LoadDropDowns() { var groupEntityType = EntityTypeCache.Read( typeof( Group ) ); var currentGroup = RockPage.GetCurrentContext( groupEntityType ) as Group; var groupIdString = Request.QueryString["groupId"]; if ( groupIdString != null ) { var groupId = groupIdString.AsInteger(); if ( currentGroup == null || currentGroup.Id != groupId ) { currentGroup = SetGroupContext( groupId, false ); } } var parts = ( GetAttributeValue( "GroupFilter" ) ?? string.Empty ).Split( '|' ); Guid? groupTypeGuid = null; Guid? rootGroupGuid = null; if ( parts.Length >= 1 ) { groupTypeGuid = parts[0].AsGuidOrNull(); if ( parts.Length >= 2 ) { rootGroupGuid = parts[1].AsGuidOrNull(); } } var rockContext = new RockContext(); var groupService = new GroupService( rockContext ); var groupTypeService = new GroupTypeService( rockContext ); IQueryable<Group> qryGroups = null; // if rootGroup is set, use that as the filter. Otherwise, use GroupType as the filter if ( rootGroupGuid.HasValue ) { var rootGroup = groupService.Get( rootGroupGuid.Value ); if ( rootGroup != null ) { qryGroups = groupService.GetAllDescendents( rootGroup.Id ).AsQueryable(); } } else if ( groupTypeGuid.HasValue ) { SetGroupTypeContext( groupTypeGuid ); if ( GetAttributeValue( "IncludeGroupTypeChildren" ).AsBoolean() ) { var childGroupTypeGuids = groupTypeService.Queryable().Where( t => t.ParentGroupTypes.Select( p => p.Guid ).Contains( groupTypeGuid.Value ) ) .Select( t => t.Guid ).ToList(); qryGroups = groupService.Queryable().Where( a => childGroupTypeGuids.Contains( a.GroupType.Guid ) ); } else { qryGroups = groupService.Queryable().Where( a => a.GroupType.Guid == groupTypeGuid.Value ); } } // no results if ( qryGroups == null ) { nbSelectGroupTypeWarning.Visible = true; lCurrentSelection.Text = string.Empty; rptGroups.Visible = false; } else { nbSelectGroupTypeWarning.Visible = false; rptGroups.Visible = true; lCurrentSelection.Text = currentGroup != null ? currentGroup.ToString() : GetAttributeValue( "NoGroupText" ); var groupList = qryGroups.OrderBy( a => a.Order ) .ThenBy( a => a.Name ).ToList() .Select( a => new GroupItem() { Name = a.Name, Id = a.Id } ) .ToList(); // check if the group can be unselected if ( !string.IsNullOrEmpty( GetAttributeValue( "ClearSelectionText" ) ) ) { var blankGroup = new GroupItem { Name = GetAttributeValue( "ClearSelectionText" ), Id = Rock.Constants.All.Id }; groupList.Insert( 0, blankGroup ); } rptGroups.DataSource = groupList; rptGroups.DataBind(); } }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The workflow action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public override bool Execute( RockContext rockContext, Model.WorkflowAction action, Object entity, out List<string> errorMessages ) { var checkInState = GetCheckInState( entity, out errorMessages ); if ( checkInState != null && checkInState.CheckIn.SearchType != null ) { var personService = new PersonService( rockContext ); var memberService = new GroupMemberService( rockContext ); GroupService groupService = new GroupService( rockContext ); PhoneNumberService phoneNumberService = new PhoneNumberService( rockContext ); int familyGroupTypeId = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid() ).Id; var dvInactive = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE.AsGuid() ); if ( checkInState.CheckIn.SearchType.Guid.Equals( new Guid( SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_PHONE_NUMBER ) ) ) { string numericPhone = checkInState.CheckIn.SearchValue.AsNumeric(); var personRecordTypeId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id; // Find the families with any member who has a phone number that contains selected value var familyQry = phoneNumberService.Queryable().AsNoTracking(); if ( checkInState.CheckInType == null || checkInState.CheckInType.PhoneSearchType == PhoneSearchType.EndsWith ) { char[] charArray = numericPhone.ToCharArray(); Array.Reverse( charArray ); familyQry = familyQry.Where( o => o.NumberReversed.StartsWith( new string( charArray ) ) ); } else { familyQry = familyQry.Where( o => o.Number.Contains( numericPhone ) ); } var tmpQry = familyQry.Join( personService.Queryable().AsNoTracking(), o => new { PersonId = o.PersonId, IsDeceased = false, RecordTypeValueId = personRecordTypeId }, p => new { PersonId = p.Id, IsDeceased = p.IsDeceased, RecordTypeValueId = p.RecordTypeValueId.Value }, ( pn, p ) => new { Person = p, PhoneNumber = pn } ) .Join( memberService.Queryable().AsNoTracking(), pn => pn.Person.Id, m => m.PersonId, ( o, m ) => new { PersonNumber = o.PhoneNumber, GroupMember = m } ); var familyIdQry = groupService.Queryable().Where( g => tmpQry.Any( o => o.GroupMember.GroupId == g.Id ) && g.GroupTypeId == familyGroupTypeId ) .Select( g => g.Id ) .Distinct(); int maxResults = checkInState.CheckInType != null ? checkInState.CheckInType.MaxSearchResults : 100; if ( maxResults > 0 ) { familyIdQry = familyIdQry.Take( maxResults ); } var familyIds = familyIdQry.ToList(); // Load the family members var familyMembers = memberService .Queryable( "Group,GroupRole,Person" ).AsNoTracking() .Where( m => familyIds.Contains( m.GroupId ) ) .ToList(); // Add each family foreach ( int familyId in familyIds ) { // Get each of the members for this family var familyMemberQry = familyMembers .Where( m => m.GroupId == familyId && m.Person.NickName != null ); if ( checkInState.CheckInType != null && checkInState.CheckInType.PreventInactivePeopele && dvInactive != null ) { familyMemberQry = familyMemberQry .Where( m => m.Person.RecordStatusValueId != dvInactive.Id ); } var thisFamilyMembers = familyMemberQry.ToList(); if ( thisFamilyMembers.Any() ) { var group = thisFamilyMembers .Select( m => m.Group ) .FirstOrDefault(); var firstNames = thisFamilyMembers .OrderBy( m => m.GroupRole.Order ) .ThenBy( m => m.Person.BirthYear ) .ThenBy( m => m.Person.BirthMonth ) .ThenBy( m => m.Person.BirthDay ) .ThenBy( m => m.Person.Gender ) .Select( m => m.Person.NickName ) .ToList(); var family = new CheckInFamily(); family.Group = group.Clone( false ); family.Caption = group.ToString(); family.SubCaption = firstNames.AsDelimited( ", " ); checkInState.CheckIn.Families.Add( family ); } } } else if ( checkInState.CheckIn.SearchType.Guid.Equals( new Guid( SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_NAME ) ) ) { var people = personService.GetByFullName( checkInState.CheckIn.SearchValue, false ).AsNoTracking(); if ( checkInState.CheckInType != null && checkInState.CheckInType.PreventInactivePeopele && dvInactive != null ) { people = people.Where( p => p.RecordStatusValueId != dvInactive.Id ); } foreach ( var person in people ) { foreach ( var group in person.Members.Where( m => m.Group.GroupTypeId == familyGroupTypeId ).Select( m => m.Group ).ToList() ) { var family = checkInState.CheckIn.Families.Where( f => f.Group.Id == group.Id ).FirstOrDefault(); if ( family == null ) { family = new CheckInFamily(); family.Group = group.Clone( false ); family.Group.LoadAttributes( rockContext ); family.Caption = group.ToString(); if ( checkInState.CheckInType == null || !checkInState.CheckInType.PreventInactivePeopele ) { family.SubCaption = memberService.GetFirstNames( group.Id ).ToList().AsDelimited( ", " ); } else { family.SubCaption = memberService.GetFirstNames( group.Id, false, false ).ToList().AsDelimited( ", " ); } checkInState.CheckIn.Families.Add( family ); } } } } else { errorMessages.Add( "Invalid Search Type" ); return false; } return true; } errorMessages.Add( "Invalid Check-in State" ); return false; }
private void LoadRegistration() { RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); AttendanceService attendanceService = new AttendanceService( rockContext ); // get list of groups of this type var groups = groupService.Queryable() .Where( g => g.GroupTypeId == _groupType.Id && g.IsActive == true ) .ToList(); var groupIds = groups.Select( g => g.Id ).ToList(); // get listing of possible attendance for groups of this type var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( GetAttributeValue( "DateRange" ) ?? "-1||" ); _schedules = attendanceService.Queryable() .Where( a => a.GroupId.HasValue && groupIds.Contains( a.GroupId.Value ) && a.StartDateTime >= dateRange.Start.Value && a.StartDateTime <= dateRange.End.Value && a.LocationId == _location.Id ) .Select( a => new ScheduleResult { Group = a.Group, Schedule = a.Schedule, Date = a.StartDateTime } ) .Distinct() .ToList(); // get personal schedules (things you already signed up for) _personalSchedules = attendanceService.Queryable() .Where( a => a.GroupId.HasValue && groupIds.Contains( a.GroupId.Value ) && a.StartDateTime >= dateRange.Start.Value && a.StartDateTime <= dateRange.End.Value && a.PersonAlias.PersonId == CurrentPersonId && a.LocationId == _location.Id && a.RSVP == RSVP.Yes) .Select( a => new ScheduleResult { Group = a.Group, Schedule = a.Schedule, Date = a.StartDateTime } ) .Distinct() .ToList(); rptScheduleDates.DataSource = _schedules.Select( s => s.Date.Date ).Distinct(); rptScheduleDates.DataBind(); }
/// <summary> /// Maps the group attendance. /// </summary> /// <param name="tableData">The table data.</param> /// <returns></returns> //private DateTime? StartDateTime { get; set;} private void MapGroupsAttendance( IQueryable<Row> tableData ) { var lookupContext = new RockContext(); int completed = 0; int totalRows = tableData.Count(); int percentage = ( totalRows - 1 ) / 100 + 1; ReportProgress( 0, string.Format( "Verifying Attendance import ({0:N0} found).", totalRows ) ); var attendanceList = new List<Rock.Model.Attendance>(); var groupService = new GroupService( lookupContext ); var existingGroupList = new List<Group>(); existingGroupList = groupService.Queryable().Where(g => g.ForeignId != null).ToList(); foreach ( var row in tableData ) { DateTime? startTime = row["StartDateTime"] as DateTime?; if ( startTime != null && startTime != DateTime.MinValue ) { int? groupId = row["GroupID"] as int?; if ( existingGroupList.Find(g => g.ForeignId == groupId.ToString()) != null ) //making sure the group has been created. { DateTime startDateTime = (DateTime)startTime; DateTime? endTime = row["EndDateTime"] as DateTime?; int? met = row["Met"] as int?; bool didAttend = true; if ( met == 0 ) { didAttend = false; } string comments = row["Comments"] as string; var attendance = new Rock.Model.Attendance(); attendance.CreatedByPersonAliasId = ImportPersonAlias.Id; attendance.ModifiedByPersonAliasId = ImportPersonAlias.Id; attendance.CreatedDateTime = DateTime.Today; attendance.ModifiedDateTime = DateTime.Today; attendance.StartDateTime = startDateTime; attendance.EndDateTime = endTime; attendance.DidAttend = didAttend; attendance.Note = comments; attendance.CampusId = 1; //Campus is needed for attendance to show in attendance analysis. attendance.GroupId = existingGroupList.Find( g => g.ForeignId == groupId.ToString() ).Id; int? individualId = row["IndividualID"] as int?; if ( individualId != null ) { attendance.PersonAliasId = GetPersonAliasId( individualId ); } ////look up Group //int? groupId = row["GroupID"] as int?; //Group group = existingGroupList.Where( g => g.ForeignId == ( groupId.ToString() ) ).FirstOrDefault(); //if ( group != null ) //{ // attendance.GroupId = group.Id; //} //no other search type right now; small group attendance not currently set up in Rock. var dvService = new DefinedValueService( lookupContext ); attendance.SearchTypeValueId = dvService.Queryable().Where( dv => dv.Value == "Phone Number" ).FirstOrDefault().Id; completed++; if ( completed % percentage < 1 ) { int percentComplete = completed / percentage; ReportProgress( percentComplete, string.Format( "Completed: {0:N0} Percent Completed: {0:N0} ", completed, percentComplete ) ); } var rockContext = new RockContext(); rockContext.WrapTransaction( () => { rockContext.Configuration.AutoDetectChangesEnabled = false; rockContext.Attendances.Add( attendance ); rockContext.SaveChanges( DisableAudit ); } ); ReportPartialProgress(); } } } }
/// <summary> /// Handles the SelectItem event of the gp control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void gp_SelectItem( object sender, EventArgs e ) { var rockContext = new RockContext(); var groupIdList = gp.SelectedValues.AsIntegerList(); var groupService = new GroupService( rockContext ); var qryGroups = groupService.GetByIds( groupIdList ); if ( qryGroups.Any() ) { var groupTypeRoleService = new GroupTypeRoleService( rockContext ); var qryGroupTypeRoles = groupTypeRoleService.Queryable(); List<int> selectedGroupTypeIds = qryGroups.Select( a => a.GroupTypeId ).Distinct().ToList(); if ( cbChildGroups.Checked ) { List<int> childGroupTypeIds = new List<int>(); foreach ( var groupId in qryGroups.Select( a => a.Id ).ToList() ) { if ( cbChildGroupsPlusDescendants.Checked ) { // get all children and descendants of the selected group(s) var descendants = groupService.GetAllDescendents( groupId ); if ( !cbIncludeInactiveGroups.Checked ) { descendants = descendants.Where( a => a.IsActive == true ); } childGroupTypeIds.AddRange( descendants.Select( a => a.GroupTypeId ).Distinct().ToList() ); } else { // get only immediate children of the selected group(s) var childGroups = groupService.Queryable().Where( a => a.ParentGroupId == groupId ); if ( !cbIncludeInactiveGroups.Checked ) { childGroups = childGroups.Where( a => a.IsActive == true ); } childGroupTypeIds.AddRange( childGroups.Select( a => a.GroupTypeId ).Distinct().ToList() ); } } childGroupTypeIds = childGroupTypeIds.Distinct().ToList(); if ( cbIncludeSelectedGroup.Checked ) { qryGroupTypeRoles = qryGroupTypeRoles.Where( a => a.GroupTypeId.HasValue && ( selectedGroupTypeIds.Contains( a.GroupTypeId.Value ) || childGroupTypeIds.Contains( a.GroupTypeId.Value ) ) ); } else { qryGroupTypeRoles = qryGroupTypeRoles.Where( a => a.GroupTypeId.HasValue && childGroupTypeIds.Contains( a.GroupTypeId.Value ) ); } } else { qryGroupTypeRoles = qryGroupTypeRoles.Where( a => a.GroupTypeId.HasValue && selectedGroupTypeIds.Contains( a.GroupTypeId.Value ) ); } var list = qryGroupTypeRoles.OrderBy( a => a.GroupType.Order ).ThenBy( a => a.GroupType.Name ).ThenBy( a => a.Order ).ThenBy( a => a.Name ).ToList(); cblRole.Items.Clear(); foreach ( var item in list ) { cblRole.Items.Add( new ListItem( string.Format( "{0} ({1})", item.Name, item.GroupType.Name ), item.Guid.ToString() ) ); } cblRole.Visible = list.Count > 0; } else { cblRole.Visible = false; } }
/// <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 ) { string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 2 ) { GroupMemberService groupMemberService = new GroupMemberService( (RockContext)serviceInstance.Context ); List<Guid> groupGuids = selectionValues[0].Split( ',' ).AsGuidList(); var groupService = new GroupService( (RockContext)serviceInstance.Context ); var groupIds = groupService.GetByGuids( groupGuids ).Select( a => a.Id ).Distinct().ToList(); bool includeChildGroups = false; bool includeChildGroupsIncludeSelected = false; bool includeChildGroupsPlusDescendants = false; bool includeInactiveGroups = false; if ( selectionValues.Length >= 3 ) { includeChildGroups = selectionValues[2].AsBooleanOrNull() ?? false; } if ( selectionValues.Length >= 6 ) { includeChildGroupsIncludeSelected = selectionValues[4].AsBooleanOrNull() ?? false; includeChildGroupsPlusDescendants = selectionValues[5].AsBooleanOrNull() ?? false; } else if ( includeChildGroups ) { // in case the selection was saved before these options where added includeChildGroupsIncludeSelected = true; includeChildGroupsPlusDescendants = true; } if ( selectionValues.Length >= 7 ) { includeInactiveGroups = selectionValues[6].AsBooleanOrNull() ?? true; ; } else { // if options where saved before this option was added, set to false, even though it would have included inactive before includeInactiveGroups = false; } GroupMemberStatus? groupMemberStatus = null; if ( selectionValues.Length >= 4 ) { groupMemberStatus = selectionValues[3].ConvertToEnumOrNull<GroupMemberStatus>(); } var groupMemberServiceQry = groupMemberService.Queryable(); if ( includeChildGroups ) { List<int> childGroupIds = new List<int>(); foreach ( var groupId in groupIds ) { if ( includeChildGroupsPlusDescendants ) { // get all children and descendants of the selected group(s) var descendants = groupService.GetAllDescendents( groupId ); if ( !includeInactiveGroups ) { descendants = descendants.Where( a => a.IsActive == true ); } childGroupIds.AddRange( descendants.Select( a => a.Id ).Distinct().ToList() ); } else { // get only immediate children of the selected group(s) var childGroups = groupService.Queryable().Where( a => a.ParentGroupId == groupId ); if ( !includeInactiveGroups ) { childGroups = childGroups.Where( a => a.IsActive == true ); } childGroupIds.AddRange( childGroups.Select( a => a.Id ) ); } } if ( includeChildGroupsIncludeSelected ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupIds.Contains( xx.GroupId ) || childGroupIds.Contains( xx.GroupId ) ); } else { groupMemberServiceQry = groupMemberServiceQry.Where( xx => childGroupIds.Contains( xx.GroupId ) ); } } else { groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupIds.Contains( xx.GroupId ) ); } if ( groupMemberStatus.HasValue ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => xx.GroupMemberStatus == groupMemberStatus.Value ); } var groupRoleGuids = selectionValues[1].Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).Select( n => n.AsGuid() ).ToList(); if ( groupRoleGuids.Count() > 0 ) { var groupRoleIds = new GroupTypeRoleService( (RockContext)serviceInstance.Context ).Queryable().Where( a => groupRoleGuids.Contains( a.Guid ) ).Select( a => a.Id ).ToList(); groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupRoleIds.Contains( xx.GroupRoleId ) ); } if ( selectionValues.Length >= 8 ) { string slidingDelimitedValues = selectionValues[7].Replace( ',', '|' ); DateRange dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( slidingDelimitedValues ); if ( dateRange.Start.HasValue ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => xx.DateTimeAdded >= dateRange.Start.Value ); } if ( dateRange.End.HasValue ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => xx.DateTimeAdded < dateRange.End.Value ); } } var qry = new PersonService( (RockContext)serviceInstance.Context ).Queryable() .Where( p => groupMemberServiceQry.Any( xx => xx.PersonId == p.Id ) ); Expression extractedFilterExpression = FilterExpressionExtractor.Extract<Rock.Model.Person>( qry, parameterExpression, "p" ); return extractedFilterExpression; } return null; }
/// <summary> /// Creates the person. /// </summary> /// <returns></returns> private Person CreatePerson() { var rockContext = new RockContext(); DefinedValueCache dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() ); DefinedValueCache dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() ); Person person = new Person(); person.FirstName = tbFirstName.Text; person.LastName = tbLastName.Text; person.Email = tbEmail.Text; person.IsEmailActive = true; person.EmailPreference = EmailPreference.EmailAllowed; person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id; if ( dvcConnectionStatus != null ) { person.ConnectionStatusValueId = dvcConnectionStatus.Id; } if ( dvcRecordStatus != null ) { person.RecordStatusValueId = dvcRecordStatus.Id; } switch ( ddlGender.SelectedValue ) { case "M": person.Gender = Gender.Male; break; case "F": person.Gender = Gender.Female; break; default: person.Gender = Gender.Unknown; break; } var birthday = bdaypBirthDay.SelectedDate; if ( birthday.HasValue ) { person.BirthMonth = birthday.Value.Month; person.BirthDay = birthday.Value.Day; if ( birthday.Value.Year != DateTime.MinValue.Year ) { person.BirthYear = birthday.Value.Year; } } bool smsSelected = false; foreach ( RepeaterItem item in rPhoneNumbers.Items ) { HiddenField hfPhoneType = item.FindControl( "hfPhoneType" ) as HiddenField; PhoneNumberBox pnbPhone = item.FindControl( "pnbPhone" ) as PhoneNumberBox; CheckBox cbUnlisted = item.FindControl( "cbUnlisted" ) as CheckBox; CheckBox cbSms = item.FindControl( "cbSms" ) as CheckBox; if ( !string.IsNullOrWhiteSpace( PhoneNumber.CleanNumber( pnbPhone.Number ) ) ) { int phoneNumberTypeId; if ( int.TryParse( hfPhoneType.Value, out phoneNumberTypeId ) ) { var phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId }; person.PhoneNumbers.Add( phoneNumber ); phoneNumber.CountryCode = PhoneNumber.CleanNumber( pnbPhone.CountryCode ); phoneNumber.Number = PhoneNumber.CleanNumber( pnbPhone.Number ); // Only allow one number to have SMS selected if ( smsSelected ) { phoneNumber.IsMessagingEnabled = false; } else { phoneNumber.IsMessagingEnabled = cbSms.Checked; smsSelected = cbSms.Checked; } phoneNumber.IsUnlisted = cbUnlisted.Checked; } } } PersonService.SaveNewPerson( person, rockContext, null, false ); // save address if ( pnlAddress.Visible ) { if ( acAddress.IsValid && !string.IsNullOrWhiteSpace(acAddress.Street1) && !string.IsNullOrWhiteSpace( acAddress.City ) && !string.IsNullOrWhiteSpace( acAddress.PostalCode ) ) { Guid locationTypeGuid = GetAttributeValue( "LocationType" ).AsGuid(); if ( locationTypeGuid != Guid.Empty ) { Guid familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid(); GroupService groupService = new GroupService( rockContext ); GroupLocationService groupLocationService = new GroupLocationService( rockContext ); var family = groupService.Queryable().Where( g => g.GroupType.Guid == familyGroupTypeGuid && g.Members.Any( m => m.PersonId == person.Id ) ).FirstOrDefault(); var groupLocation = new GroupLocation(); groupLocation.GroupId = family.Id; groupLocationService.Add( groupLocation ); var location = new LocationService( rockContext ).Get( acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country ); groupLocation.Location = location; groupLocation.GroupLocationTypeValueId = DefinedValueCache.Read( locationTypeGuid).Id; groupLocation.IsMailingLocation = true; groupLocation.IsMappedLocation = true; rockContext.SaveChanges(); } } } return person; }
/// <summary> /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set. /// </summary> /// <param name="entityType">The type of entity in the result set.</param> /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param> /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param> /// <param name="selection">A formatted string representing the filter settings.</param> /// <returns> /// A Linq Expression that can be used to filter an IQueryable. /// </returns> public override Expression GetExpression( Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection ) { var settings = new SelectSettings( selection ); var context = (RockContext)serviceInstance.Context; // // Evaluate the Data View that defines the candidate Groups. // var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent( settings.DataViewGuid, context ); var groupService = new GroupService( context ); var groupQuery = groupService.Queryable(); if (dataView != null) { groupQuery = DataComponentSettingsHelper.FilterByDataView( groupQuery, dataView, groupService ); } else { // Apply a default Group filter to only show Groups that would be visible in a Group List. groupQuery = groupQuery.Where( x => x.GroupType.ShowInGroupList ); } var groupKeys = groupQuery.Select( x => x.Id ); // // Construct the Query to return the list of Group Members matching the filter conditions. // var groupMemberQuery = new GroupMemberService( context ).Queryable(); // Filter By Group. groupMemberQuery = groupMemberQuery.Where( gm => groupKeys.Contains( gm.GroupId ) ); var selectExpression = FilterExpressionExtractor.Extract<Model.GroupMember>( groupMemberQuery, parameterExpression, "gm" ); return selectExpression; }
public bool FindDuplicates() { Duplicates = new Dictionary<Guid, List<Person>>(); var rockContext = new RockContext(); var locationService = new LocationService( rockContext ); var groupService = new GroupService( rockContext ); var personService = new PersonService( rockContext ); // Find any other group members (any group) that have same location var othersAtAddress = new List<int>(); string locationKey = GetLocationKey(); if ( !string.IsNullOrWhiteSpace(locationKey) && _verifiedLocations.ContainsKey( locationKey)) { int? locationId = _verifiedLocations[locationKey]; if ( locationId.HasValue ) { var location = locationService.Get( locationId.Value ); if ( location != null ) { othersAtAddress = groupService .Queryable().AsNoTracking() .Where( g => g.GroupTypeId == _locationType.Id && g.GroupLocations.Any( l => l.LocationId == location.Id ) ) .SelectMany( g => g.Members ) .Select( m => m.PersonId ) .ToList(); } } } foreach ( var person in GroupMembers .Where( m => m.Person != null && m.Person.FirstName != "" ) .Select( m => m.Person ) ) { bool otherCriteria = false; var personQry = personService .Queryable().AsNoTracking() .Where( p => p.FirstName == person.FirstName || p.NickName == person.FirstName ); if ( othersAtAddress.Any() ) { personQry = personQry .Where( p => othersAtAddress.Contains( p.Id ) ); } if ( person.BirthDate.HasValue ) { otherCriteria = true; personQry = personQry .Where( p => p.BirthDate.HasValue && p.BirthDate.Value == person.BirthDate.Value ); } if ( _homePhone != null ) { var homePhoneNumber = person.PhoneNumbers.Where( p => p.NumberTypeValueId == _homePhone.Id ).FirstOrDefault(); if ( homePhoneNumber != null ) { otherCriteria = true; personQry = personQry .Where( p => p.PhoneNumbers.Any( n => n.NumberTypeValueId == _homePhone.Id && n.Number == homePhoneNumber.Number ) ); } } if ( _cellPhone != null ) { var cellPhoneNumber = person.PhoneNumbers.Where( p => p.NumberTypeValueId == _cellPhone.Id ).FirstOrDefault(); if ( cellPhoneNumber != null ) { otherCriteria = true; personQry = personQry .Where( p => p.PhoneNumbers.Any( n => n.NumberTypeValueId == _cellPhone.Id && n.Number == cellPhoneNumber.Number ) ); } } if ( !string.IsNullOrWhiteSpace( person.Email ) ) { otherCriteria = true; personQry = personQry .Where( p => p.Email == person.Email ); } var dups = new List<Person>(); if ( otherCriteria ) { // If a birthday, email, phone, or address was entered, find anyone with same info and same first name dups = personQry.ToList(); } else { // otherwise find people with same first and last name dups = personQry .Where( p => p.LastName == person.LastName ) .ToList(); } if ( dups.Any() ) { Duplicates.Add( person.Guid, dups ); } } return Duplicates.Any(); }
/// <summary> /// Maps the attendance. /// </summary> /// <param name="tableData">The table data.</param> /// <returns></returns> //private DateTime? StartDateTime { get; set;} private void MapAttendance( IQueryable<Row> tableData ) { var lookupContext = new RockContext(); int completed = 0; int totalRows = tableData.Count(); int percentage = ( totalRows - 1 ) / 100 + 1; ReportProgress( 0, string.Format( "Verifying Attendance import ({0:N0} found).", totalRows ) ); var attendanceList = new List<Rock.Model.Attendance>(); var groupService = new GroupService( lookupContext ); var existingGroupList = new List<Group>(); existingGroupList = groupService.Queryable().ToList(); foreach ( var row in tableData ) { DateTime? startTime = row["Start_Date_Time"] as DateTime?; if ( startTime != null && startTime != DateTime.MinValue) { DateTime startDateTime = (DateTime)startTime; if ( startDateTime.Year == 2014 && startDateTime.Month >= 1 && startDateTime.Month <= 8 ) { //startDateTime = BruteForceDateTime(startTime); var attendance = new Rock.Model.Attendance(); attendance.CreatedByPersonAliasId = ImportPersonAlias.Id; attendance.ModifiedByPersonAliasId = ImportPersonAlias.Id; attendance.CreatedDateTime = DateTime.Today; attendance.ModifiedDateTime = DateTime.Today; attendance.StartDateTime = startDateTime; //(DateTime)startTime; attendance.DidAttend = true; attendance.CampusId = 1; //Campus is needed for attendance to show in attendance analysis. //string position = row["CheckedInAs"] as string; //string jobTitle = row["Job_Title"] as string; //string machineName = row["Checkin_Machine_Name"] as string; int? rlcId = row["RLC_ID"] as int?; int? individualId = row["Individual_ID"] as int?; if ( individualId != null ) { attendance.PersonAliasId = GetPersonAliasId( individualId ); } DateTime? checkInTime = row["Check_In_Time"] as DateTime?; if ( checkInTime != null ) { // set the start time to the time they actually checked in. If null it maintains Start_Date_Time attendance.StartDateTime = (DateTime)checkInTime; //BruteForceDateTime( checkInTime ); } DateTime? checkOutTime = row["Check_Out_Time"] as DateTime?; if ( checkOutTime != null ) { attendance.EndDateTime = (DateTime)checkOutTime; //BruteForceDateTime( checkOutTime ); } //string f1AttendanceCode = row["Tag_Code"] as string; //if ( f1AttendanceCode != null ) //{ // attendance.AttendanceCode = new Rock.Model.AttendanceCode(); // attendance.AttendanceCode.Code = f1AttendanceCode; //} string f1AttendanceCheckedInAs = row["CheckedInAs"] as string; if ( f1AttendanceCheckedInAs != null ) { attendance.Note = f1AttendanceCheckedInAs; } // look up location, schedule, and device -- all of these fields can be null if need be attendance.LocationId = GetLocationId( Convert.ToInt32( rlcId ) ); //look up Group Group rlcGroup = existingGroupList.Where( g => g.ForeignId == ( rlcId.ToString() ) ).FirstOrDefault(); if ( rlcGroup != null ) { attendance.GroupId = rlcGroup.Id; } var dvService = new DefinedValueService( lookupContext ); attendance.SearchTypeValueId = dvService.Queryable().Where( dv => dv.Value == "Phone Number" ).FirstOrDefault().Id; //ReportProgress( 0, string.Format( "{0},{1},{2},{3},{4},{5},{6},{7},{8}", individualId,rlcId,rlcGroup.Name,attendance.CreatedByPersonAliasId,attendance.ModifiedByPersonAliasId,attendance.StartDateTime,attendance.DidAttend,attendance.AttendanceCode,attendance.LocationId ) ); //look into creating DeviceIds and Locations (Generic) // Other Attributes to create: // Tag_Comment // BreakoutGroup_Name // Pager_Code //attendanceList.Add( attendance ); completed++; if ( completed % percentage < 1 ) { int percentComplete = completed / percentage; ReportProgress( percentComplete, string.Format( "Completed: {0:N0} Percent Completed: {0:N0} ", completed, percentComplete ) ); } // else if ( completed % ReportingNumber < 1 ) // { // var rockContext = new RockContext(); // rockContext.WrapTransaction( () => //{ // rockContext.Configuration.AutoDetectChangesEnabled = false; // rockContext.Attendances.AddRange( attendanceList ); // rockContext.SaveChanges( DisableAudit ); //} ); // ReportPartialProgress(); // } var rockContext = new RockContext(); rockContext.WrapTransaction( () => { rockContext.Configuration.AutoDetectChangesEnabled = false; rockContext.Attendances.Add( attendance ); rockContext.SaveChanges( DisableAudit ); } ); ReportPartialProgress(); } } } }
/// <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 ) { var settings = new GroupBranchFilterSettings( selection ); if ( !settings.IsValid() ) { return null; } var groupService = new GroupService( (RockContext)serviceInstance.Context ); // Get the qualifying Groups. var parentGroup = groupService.Get( settings.ParentGroupId ); var groupIdList = GetGroupBranchKeys( groupService, parentGroup, settings.IncludedGroups ); // Filter by Groups var groupsQry = groupService.Queryable().Where( x => groupIdList.Contains( x.Id ) ); var qry = groupService.Queryable().Where( g => groupsQry.Any( x => x.Id == g.Id ) ); var extractedFilterExpression = FilterExpressionExtractor.Extract<Model.Group>( qry, parameterExpression, "g" ); return extractedFilterExpression; }
/// <summary> /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set. /// </summary> /// <param name="entityType">The type of entity in the result set.</param> /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param> /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param> /// <param name="selection">A formatted string representing the filter settings.</param> /// <returns> /// A Linq Expression that can be used to filter an IQueryable. /// </returns> public override Expression GetExpression( Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection ) { var settings = new SelectSettings( selection ); var context = (RockContext)serviceInstance.Context; // // Evaluate the Data View that defines the candidate Groups. // var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent( settings.DataViewGuid, context ); var groupService = new GroupService( context ); var groupQuery = groupService.Queryable(); if (dataView != null) { groupQuery = DataComponentSettingsHelper.FilterByDataView( groupQuery, dataView, groupService ); } else { // Apply a default Group filter to only show Groups that would be visible in a Group List. groupQuery = groupQuery.Where( x => x.GroupType.ShowInGroupList ); } var groupKeys = groupQuery.Select( x => x.Id ); // // Construct the Query to return the list of Group Members matching the filter conditions. // var groupMemberQuery = new GroupMemberService( context ).Queryable(); // Filter By Group. groupMemberQuery = groupMemberQuery.Where( x => groupKeys.Contains( x.GroupId ) ); // Filter By Group Role Type. switch ( settings.RoleType ) { case RoleTypeSpecifier.Member: groupMemberQuery = groupMemberQuery.Where( x => !x.GroupRole.IsLeader ); break; case RoleTypeSpecifier.Leader: groupMemberQuery = groupMemberQuery.Where( x => x.GroupRole.IsLeader ); break; } // Filter by Group Member Status. if ( settings.MemberStatus.HasValue ) { groupMemberQuery = groupMemberQuery.Where( x => x.GroupMemberStatus == settings.MemberStatus.Value ); } // // Create a Select Expression to return the Person records referenced by the Group Members. // var personGroupsQuery = new PersonService( context ).Queryable() .Where( p => groupMemberQuery.Select( gm => gm.PersonId ).Contains( p.Id ) ); var selectExpression = FilterExpressionExtractor.Extract<Model.Person>( personGroupsQuery, parameterExpression, "p" ); return selectExpression; }
/// <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; bool requirePasswordReset = dataMap.GetBoolean( "RequirePasswordReset" ); int groupsSynced = 0; int groupsChanged = 0; try { // get groups set to sync GroupService groupService = new GroupService( new RockContext() ); var groupIdsThatSync = groupService.Queryable().Where( g => g.SyncDataViewId != null ).Select( a => a.Id ).ToList(); foreach ( var syncGroupId in groupIdsThatSync ) { bool hasGroupChanged = false; // use a fresh rockContext per group so that ChangeTracker doesn't get bogged down using ( var rockContext = new RockContext() ) { var syncGroup = new GroupService( rockContext ).Get( syncGroupId ); GroupMemberService groupMemberService = new GroupMemberService( rockContext ); // increase the timeout just in case the dataview source is slow rockContext.Database.CommandTimeout = 180; var syncSource = new DataViewService( rockContext ).Get( syncGroup.SyncDataViewId.Value ); // ensure this is a person dataview bool isPersonDataSet = syncSource.EntityTypeId == EntityTypeCache.Read( typeof( Rock.Model.Person ) ).Id; if ( isPersonDataSet ) { SortProperty sortById = new SortProperty(); sortById.Property = "Id"; sortById.Direction = System.Web.UI.WebControls.SortDirection.Ascending; List<string> errorMessages = new List<string>(); var personService = new PersonService( rockContext ); var parameterExpression = personService.ParameterExpression; var whereExpression = syncSource.GetExpression( personService, parameterExpression, out errorMessages ); var sourceItems = personService.Get( parameterExpression, whereExpression ).Select( q => q.Id ).ToList(); var targetItems = groupMemberService.Queryable().Where( gm => gm.GroupId == syncGroup.Id ).ToList(); // delete items from the target not in the source foreach ( var targetItem in targetItems.Where( t => !sourceItems.Contains( t.PersonId ) ) ) { // made a clone of the person as it will be detached when the group member is deleted. Also // saving the delete before the email is sent in case an exception occurs so the user doesn't // get an email everytime the agent runs. Person recipient = (Person)targetItem.Person.Clone(); groupMemberService.Delete( targetItem ); rockContext.SaveChanges(); hasGroupChanged = true; if ( syncGroup.ExitSystemEmailId.HasValue ) { SendExitEmail( syncGroup.ExitSystemEmailId.Value, recipient, syncGroup ); } } // add items not in target but in the source foreach ( var sourceItem in sourceItems.Where( s => !targetItems.Select( t => t.PersonId ).Contains( s ) ) ) { // add source to target var newGroupMember = new GroupMember { Id = 0 }; newGroupMember.PersonId = sourceItem; newGroupMember.Group = syncGroup; newGroupMember.GroupMemberStatus = GroupMemberStatus.Active; newGroupMember.GroupRoleId = syncGroup.GroupType.DefaultGroupRoleId ?? syncGroup.GroupType.Roles.FirstOrDefault().Id; groupMemberService.Add( newGroupMember ); hasGroupChanged = true; if ( syncGroup.WelcomeSystemEmailId.HasValue ) { SendWelcomeEmail( syncGroup.WelcomeSystemEmailId.Value, sourceItem, syncGroup, syncGroup.AddUserAccountsDuringSync ?? false, requirePasswordReset ); } } if ( hasGroupChanged ) { groupsChanged++; } groupsSynced++; rockContext.SaveChanges(); if ( hasGroupChanged && ( syncGroup.IsSecurityRole || syncGroup.GroupType.Guid.Equals( Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid() ) ) ) { Rock.Security.Role.Flush( syncGroup.Id ); } } } } var resultMessage = string.Empty; if ( groupsSynced == 0 ) { resultMessage = "No groups to sync"; } else if ( groupsSynced == 1 ) { resultMessage = "1 group was sync'ed"; } else { resultMessage = string.Format( "{0} groups were sync'ed", groupsSynced ); } resultMessage += string.Format( " and {0} groups where changed", groupsChanged ); context.Result = resultMessage; } catch ( System.Exception ex ) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException( ex, context2 ); throw; } }
/// <summary> /// Handles the Click event of the btnDelete control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnDelete_Click( object sender, EventArgs e ) { int? parentGroupId = null; RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); AuthService authService = new AuthService( rockContext ); Group group = groupService.Get( hfGroupId.Value.AsInteger() ); if ( group != null ) { if ( !group.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) ) { mdDeleteWarning.Show( "You are not authorized to delete this group.", ModalAlertType.Information ); return; } parentGroupId = group.ParentGroupId; string errorMessage; if ( !groupService.CanDelete( group, out errorMessage ) ) { mdDeleteWarning.Show( errorMessage, ModalAlertType.Information ); return; } bool isSecurityRoleGroup = group.IsActive && ( group.IsSecurityRole || group.GroupType.Guid.Equals( Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid() ) ); if ( isSecurityRoleGroup ) { Rock.Security.Role.Flush( group.Id ); foreach ( var auth in authService.Queryable().Where( a => a.GroupId == group.Id ).ToList() ) { authService.Delete( auth ); } } // If group has a non-named schedule, delete the schedule record. if ( group.ScheduleId.HasValue ) { var scheduleService = new ScheduleService( rockContext ); var schedule = scheduleService.Get( group.ScheduleId.Value ); if ( schedule != null && schedule.ScheduleType != ScheduleType.Named ) { // Make sure this is the only group trying to use this schedule. if ( !groupService.Queryable().Where( g => g.ScheduleId == schedule.Id && g.Id != group.Id ).Any() ) { scheduleService.Delete( schedule ); } } } groupService.Delete( group ); rockContext.SaveChanges(); if ( isSecurityRoleGroup ) { Rock.Security.Authorization.Flush(); } } // reload page, selecting the deleted group's parent var qryParams = new Dictionary<string, string>(); if ( parentGroupId != null ) { qryParams["GroupId"] = parentGroupId.ToString(); } qryParams["ExpandedIds"] = PageParameter( "ExpandedIds" ); NavigateToPage( RockPage.Guid, qryParams ); }
/// <summary> /// Gets the Location ID of a location already in Rock. --looks under dbo.group.foreignId then compares group.description with location name. /// </summary> /// <param name="rlcID">rlc ID </param> /// <returns>Location ID</returns> private int GetLocationId(int rlcId) { var lookupContext = new RockContext(); var groupService = new GroupService(lookupContext); var rlcGroup = new Group(); string rlcIdString = rlcId.ToString(); rlcGroup = groupService.Queryable().Where(g => g.ForeignId == (rlcIdString)).FirstOrDefault(); string groupLocation = String.Empty; if ( rlcGroup != null ) { groupLocation = rlcGroup.Description; } if (!String.IsNullOrWhiteSpace(groupLocation)) { var locationService = new LocationService(lookupContext); var location = new List<Location>(); location = locationService.Queryable().Where(l => l.ParentLocationId.HasValue).ToList(); switch (groupLocation) { case "A201": { return location.Where(l => l.Name == "A201").FirstOrDefault().Id; } case "A202": { return location.Where(l => l.Name == "A202").FirstOrDefault().Id; } case "Area X Basketball": { return location.Where(l => l.Name == "Area X").FirstOrDefault().Id; } case "Area X Main Area": { return location.Where(l => l.Name == "Area X").FirstOrDefault().Id; } case "Auditorium": { return location.Where(l => l.Name == "Auditorium").FirstOrDefault().Id; } case "Auditorium Recording Booth": { return location.Where(l => l.Name == "Auditorium").FirstOrDefault().Id; } case "Auditorium Sound Booth": { return location.Where(l => l.Name == "Auditorium").FirstOrDefault().Id; } case "Bookstore Downstairs": { return location.Where(l => l.Name == "Bookstore").FirstOrDefault().Id; } case "Bookstore Upstairs": { return location.Where(l => l.Name == "Bookstore").FirstOrDefault().Id; } case "Bug 117": { return location.Where(l => l.Name == "Bug").FirstOrDefault().Id; } case "Bunny 114": { return location.Where(l => l.Name == "Bunny").FirstOrDefault().Id; } case "Butterfly 108": { return location.Where(l => l.Name == "Butterfly").FirstOrDefault().Id; } case "C201": { return location.Where(l => l.Name == "C201").FirstOrDefault().Id; } case "C202": { return location.Where(l => l.Name == "C202").FirstOrDefault().Id; } case "C203": { return location.Where(l => l.Name == "C203").FirstOrDefault().Id; } case "Car 1": { return location.Where(l => l.Name == "Car 1").FirstOrDefault().Id; } case "Car 10": { return location.Where(l => l.Name == "Car 10").FirstOrDefault().Id; } case "Car 2": { return location.Where(l => l.Name == "Car 2").FirstOrDefault().Id; } case "Car 3": { return location.Where(l => l.Name == "Car 3").FirstOrDefault().Id; } case "Car 4": { return location.Where(l => l.Name == "Car 4").FirstOrDefault().Id; } case "Car 5": { return location.Where(l => l.Name == "Car 5").FirstOrDefault().Id; } case "Car 6": { return location.Where(l => l.Name == "Car 6").FirstOrDefault().Id; } case "Car 7": { return location.Where(l => l.Name == "Car 7").FirstOrDefault().Id; } case "Car 8": { return location.Where(l => l.Name == "Car 8").FirstOrDefault().Id; } case "Car 9": { return location.Where(l => l.Name == "Car 9").FirstOrDefault().Id; } case "Catapiller 107": { return location.Where( l => l.Name == "Caterpillar" ).FirstOrDefault().Id; } case "Chapel": { return location.Where(l => l.Name == "Chapel").FirstOrDefault().Id; } case "Chapel 101": { return location.Where(l => l.Name == "Chapel 101").FirstOrDefault().Id; } case "Chapel 102": { return location.Where( l => l.Name == "Chapel 102" ).FirstOrDefault().Id; } case "Chapel Hallway": { return location.Where(l => l.Name == "Chapel Entrance").FirstOrDefault().Id; } case "Chapel Sound Booth": { return location.Where(l => l.Name == "Chapel").FirstOrDefault().Id; } //case "Children's Lobby": //Kayla doesn't know what location this is // { // return location.Where(l => l.Name == "A201").FirstOrDefault().Id; // } case "College House": { return location.Where(l => l.Name == "The College House").FirstOrDefault().Id; } case "Communion Prep Room": { return location.Where(l => l.Name == "Communion Prep Room").FirstOrDefault().Id; } case "Cross Street Classroom": { return location.Where(l => l.Name == "Cross Street").FirstOrDefault().Id; } case "Cross Street Main Area": { return location.Where(l => l.Name == "Cross Street").FirstOrDefault().Id; } case "Crossroads Station Registration": { return location.Where(l => l.Name == "Crossroads Station").FirstOrDefault().Id; } case "Decision Room A": { return location.Where(l => l.Name == "Decision Room - A").FirstOrDefault().Id; } case "Decision Room B": { return location.Where(l => l.Name == "Decision Room - B").FirstOrDefault().Id; } case "Decision Room C": { return location.Where( l => l.Name == "Decision Room - C" ).FirstOrDefault().Id; } case "Duck 116": { return location.Where(l => l.Name == "Duck").FirstOrDefault().Id; } case "Giggleville Hallway": { return location.Where(l => l.Name == "Giggleville").FirstOrDefault().Id; } case "Giggleville Registration": { return location.Where(l => l.Name == "Giggleville").FirstOrDefault().Id; } case "Grand Hall": { return location.Where(l => l.Name == "Grand Hall").FirstOrDefault().Id; } case "Grand Hall 105": { return location.Where(l => l.Name == "Grand Hall").FirstOrDefault().Id; } case "Helping Hands House": { return location.Where(l => l.Name == "Helping Hands").FirstOrDefault().Id; } case "Kitchen": { return location.Where(l => l.Name == "Kitchen").FirstOrDefault().Id; } case "Lamb 115": { return location.Where(l => l.Name == "Lamb").FirstOrDefault().Id; } case "Main Lobby": { return location.Where(l => l.Name == "Main Lobby").FirstOrDefault().Id; } case "Main Lobby Upstairs": { return location.Where(l => l.Name == "Main Lobby").FirstOrDefault().Id; } case "Music Suite Main Area": { return location.Where(l => l.Name == "Music Suite").FirstOrDefault().Id; } case "Music Suite Room B": { return location.Where(l => l.Name == "Music Suite").FirstOrDefault().Id; } case "North Lobby": { return location.Where(l => l.Name == "North Lobby").FirstOrDefault().Id; } case "North Lobby Upstairs": { return location.Where(l => l.Name == "North Lobby").FirstOrDefault().Id; } case "Parking Lot A": { return location.Where(l => l.Name == "Parking Lot A").FirstOrDefault().Id; } case "Parking Lot B": { return location.Where(l => l.Name == "Parking Lot B").FirstOrDefault().Id; } case "Parking Lot C": { return location.Where(l => l.Name == "Parking Lot C").FirstOrDefault().Id; } case "Parking Lot D": { return location.Where(l => l.Name == "Parking Lot D").FirstOrDefault().Id; } case "Patio 1A": { return location.Where(l => l.Name == "Patio 1A").FirstOrDefault().Id; } case "Patio 1B": { return location.Where(l => l.Name == "Patio 1B").FirstOrDefault().Id; } case "Patio 2A": { return location.Where(l => l.Name == "Patio 2A").FirstOrDefault().Id; } case "Patio 2B": { return location.Where(l => l.Name == "Patio 2B").FirstOrDefault().Id; } case "Patio 2C": { return location.Where(l => l.Name == "Patio 2C").FirstOrDefault().Id; } case "Patio 3A": { return location.Where(l => l.Name == "Patio 3A").FirstOrDefault().Id; } case "Patio 3B": { return location.Where(l => l.Name == "Patio 3B").FirstOrDefault().Id; } case "Patio 3C": { return location.Where(l => l.Name == "Patio 3C").FirstOrDefault().Id; } case "Patio 4A": { return location.Where(l => l.Name == "Patio 4A").FirstOrDefault().Id; } case "Patio 4B": { return location.Where(l => l.Name == "Patio 4B").FirstOrDefault().Id; } case "Prayer Room": { return location.Where(l => l.Name == "Prayer Room").FirstOrDefault().Id; } case "Puppy 118": { return location.Where(l => l.Name == "Puppy").FirstOrDefault().Id; } case "South Lobby": { return location.Where(l => l.Name == "South Lobby").FirstOrDefault().Id; } case "Sportcenter": { return location.Where(l => l.Name == "SportCenter").FirstOrDefault().Id; } case "Squirrel 113": { return location.Where(l => l.Name == "Squirrel").FirstOrDefault().Id; } case "Texas Hall - Dallas": { return location.Where(l => l.Name == "Dallas").FirstOrDefault().Id; } case "Texas Hall - Fort Worth": { return location.Where(l => l.Name == "Fort Worth").FirstOrDefault().Id; } case "Texas Hall - Houston": { return location.Where(l => l.Name == "Houston").FirstOrDefault().Id; } case "Texas Hall - San Antonio": { return location.Where(l => l.Name == "San Antonio").FirstOrDefault().Id; } case "Youth Cafe": { return location.Where(l => l.Name == "Doulos").FirstOrDefault().Id; } case "Youth Lobby": { return location.Where(l => l.Name == "Doulos").FirstOrDefault().Id; } case "Youth Main Area": { return location.Where(l => l.Name == "Doulos").FirstOrDefault().Id; } default: return location.Where(l => l.Name == "Main Building").FirstOrDefault().Id; } } else { var locationService = new LocationService(lookupContext); var location = new Location(); location = locationService.Queryable().Where(l => l.Name == "Main Building").FirstOrDefault(); return location.Id; } }
/// <summary> /// Handles the Click event of the btnDelete control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnDelete_Click( object sender, EventArgs e ) { var familyGroupId = _family.Id; var rockContext = new RockContext(); var familyMemberService = new GroupMemberService( rockContext ); var familyMembers = familyMemberService.GetByGroupId( familyGroupId, true ); if (familyMembers.Count() == 1) { var fm = familyMembers.FirstOrDefault(); // If the person's giving group id is this family, change their giving group id to null if ( fm.Person.GivingGroupId == fm.GroupId ) { var personService = new PersonService( rockContext ); var person = personService.Get( fm.PersonId ); var demographicChanges = new List<string>(); History.EvaluateChange( demographicChanges, "Giving Group", person.GivingGroup.Name, "" ); person.GivingGroupId = null; HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), person.Id, demographicChanges ); rockContext.SaveChanges(); } // remove person from family var oldMemberChanges = new List<string>(); History.EvaluateChange( oldMemberChanges, "Role", fm.GroupRole.Name, string.Empty ); History.EvaluateChange( oldMemberChanges, "Family", fm.Group.Name, string.Empty ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.Person.Id, oldMemberChanges, fm.Group.Name, typeof( Group ), fm.Group.Id ); familyMemberService.Delete( fm ); rockContext.SaveChanges(); } var familyService = new GroupService( rockContext ); // get the family that we want to delete (if it has no members ) var family = familyService.Queryable() .Where( g => g.Id == familyGroupId && !g.Members.Any() ) .FirstOrDefault(); if ( family != null ) { familyService.Delete( family ); rockContext.SaveChanges(); } Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false ); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { // confirmation was disabled by btnSave on client-side. So if returning without a redirect, // it should be enabled. If returning with a redirect, the control won't be updated to reflect // confirmation being enabled, so it's ok to enable it here confirmExit.Enabled = true; if ( Page.IsValid ) { confirmExit.Enabled = true; RockTransactionScope.WrapTransaction( () => { var rockContext = new RockContext(); var familyService = new GroupService( rockContext ); var familyMemberService = new GroupMemberService( rockContext ); var personService = new PersonService( rockContext ); var historyService = new HistoryService( rockContext ); var familyChanges = new List<string>(); // SAVE FAMILY _family = familyService.Get( _family.Id ); History.EvaluateChange( familyChanges, "Family Name", _family.Name, tbFamilyName.Text ); _family.Name = tbFamilyName.Text; int? campusId = cpCampus.SelectedValueAsInt(); if ( _family.CampusId != campusId ) { History.EvaluateChange( familyChanges, "Campus", _family.CampusId.HasValue ? CampusCache.Read( _family.CampusId.Value ).Name : string.Empty, campusId.HasValue ? CampusCache.Read( campusId.Value ).Name : string.Empty ); _family.CampusId = campusId; } var familyGroupTypeId = _family.GroupTypeId; rockContext.SaveChanges(); // SAVE FAMILY MEMBERS int? recordStatusValueID = ddlRecordStatus.SelectedValueAsInt(); int? reasonValueId = ddlReason.SelectedValueAsInt(); var newFamilies = new List<Group>(); foreach ( var familyMember in FamilyMembers ) { var memberChanges = new List<string>(); var demographicChanges = new List<string>(); var role = familyRoles.Where( r => r.Guid.Equals( familyMember.RoleGuid ) ).FirstOrDefault(); if ( role == null ) { role = familyRoles.FirstOrDefault(); } bool isChild = role != null && role.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD ) ); // People added to family (new or from other family) if ( !familyMember.ExistingFamilyMember ) { var groupMember = new GroupMember(); if ( familyMember.Id == -1 ) { // added new person demographicChanges.Add( "Created" ); var person = new Person(); person.FirstName = familyMember.FirstName; person.NickName = familyMember.NickName; History.EvaluateChange( demographicChanges, "First Name", string.Empty, person.FirstName ); person.LastName = familyMember.LastName; History.EvaluateChange( demographicChanges, "Last Name", string.Empty, person.LastName ); person.Gender = familyMember.Gender; History.EvaluateChange( demographicChanges, "Gender", null, person.Gender ); person.BirthDate = familyMember.BirthDate; History.EvaluateChange( demographicChanges, "Birth Date", null, person.BirthDate ); if ( !isChild ) { person.GivingGroupId = _family.Id; History.EvaluateChange( demographicChanges, "Giving Group", string.Empty, _family.Name ); } person.EmailPreference = EmailPreference.EmailAllowed; groupMember.Person = person; } else { // added from other family groupMember.Person = personService.Get( familyMember.Id ); } if ( recordStatusValueID > 0 ) { History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) ); groupMember.Person.RecordStatusValueId = recordStatusValueID; History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) ); groupMember.Person.RecordStatusReasonValueId = reasonValueId; } groupMember.GroupId = _family.Id; if ( role != null ) { History.EvaluateChange( memberChanges, "Role", string.Empty, role.Name ); groupMember.GroupRoleId = role.Id; } if ( groupMember.Person != null ) { familyMemberService.Add( groupMember ); rockContext.SaveChanges(); familyMember.Id = groupMember.Person.Id; } } else { // existing family members var groupMember = familyMemberService.Queryable( "Person" ).Where( m => m.PersonId == familyMember.Id && m.Group.GroupTypeId == familyGroupTypeId && m.GroupId == _family.Id ).FirstOrDefault(); if ( groupMember != null ) { if ( familyMember.Removed ) { var newFamilyChanges = new List<string>(); // Family member was removed and should be created in their own new family var newFamily = new Group(); newFamily.Name = familyMember.LastName + " Family"; History.EvaluateChange( newFamilyChanges, "Family", string.Empty, newFamily.Name ); newFamily.GroupTypeId = familyGroupTypeId; if ( _family.CampusId.HasValue ) { History.EvaluateChange( newFamilyChanges, "Campus", string.Empty, CampusCache.Read( _family.CampusId.Value ).Name ); } newFamily.CampusId = _family.CampusId; familyService.Add( newFamily ); rockContext.SaveChanges(); // If person's previous giving group was this family, set it to their new family id if ( groupMember.Person.GivingGroup != null && groupMember.Person.GivingGroupId == _family.Id ) { History.EvaluateChange( demographicChanges, "Giving Group", groupMember.Person.GivingGroup.Name, _family.Name ); groupMember.Person.GivingGroupId = newFamily.Id; } groupMember.Group = newFamily; rockContext.SaveChanges(); var newMemberChanges = new List<string>(); History.EvaluateChange( newMemberChanges, "Role", string.Empty, groupMember.GroupRole.Name ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), groupMember.Person.Id, newFamilyChanges, newFamily.Name, typeof( Group ), newFamily.Id ); newFamilies.Add( newFamily ); History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole.Name, string.Empty ); } else { // Existing member was not remvoved if ( role != null ) { History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole != null ? groupMember.GroupRole.Name : string.Empty, role.Name ); groupMember.GroupRoleId = role.Id; if ( recordStatusValueID > 0 ) { History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) ); groupMember.Person.RecordStatusValueId = recordStatusValueID; History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) ); groupMember.Person.RecordStatusReasonValueId = reasonValueId; } rockContext.SaveChanges(); } } } } // Remove anyone that was moved from another family if ( familyMember.RemoveFromOtherFamilies ) { var otherFamilies = familyMemberService.Queryable() .Where( m => m.PersonId == familyMember.Id && m.Group.GroupTypeId == familyGroupTypeId && m.GroupId != _family.Id ) .ToList(); foreach ( var otherFamilyMember in otherFamilies ) { var fm = familyMemberService.Get( otherFamilyMember.Id ); // If the person's giving group id was the family they are being removed from, update it to this new family's id if ( fm.Person.GivingGroupId == fm.GroupId ) { var person = personService.Get( fm.PersonId ); History.EvaluateChange( demographicChanges, "Giving Group", person.GivingGroup.Name, _family.Name ); person.GivingGroupId = _family.Id; rockContext.SaveChanges(); } var oldMemberChanges = new List<string>(); History.EvaluateChange( oldMemberChanges, "Role", fm.GroupRole.Name, string.Empty ); History.EvaluateChange( oldMemberChanges, "Family", fm.Group.Name, string.Empty ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.Person.Id, oldMemberChanges, fm.Group.Name, typeof( Group ), fm.Group.Id ); familyMemberService.Delete( fm ); rockContext.SaveChanges(); var f = familyService.Queryable() .Where( g => g.Id == otherFamilyMember.GroupId && !g.Members.Any() ) .FirstOrDefault(); if ( f != null ) { familyService.Delete( f ); rockContext.SaveChanges(); } } } HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), familyMember.Id, demographicChanges ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), familyMember.Id, memberChanges, _family.Name, typeof( Group ), _family.Id ); } // SAVE LOCATIONS var groupLocationService = new GroupLocationService( rockContext ); // delete any group locations that were removed var remainingLocationIds = FamilyAddresses.Where( a => a.Id > 0 ).Select( a => a.Id ).ToList(); foreach ( var removedLocation in groupLocationService.Queryable( "GroupLocationTypeValue,Location" ) .Where( l => l.GroupId == _family.Id && !remainingLocationIds.Contains( l.Id ) ) ) { History.EvaluateChange( familyChanges, removedLocation.GroupLocationTypeValue.Name + " Location", removedLocation.Location.ToString(), string.Empty ); groupLocationService.Delete( removedLocation ); } rockContext.SaveChanges(); foreach ( var familyAddress in FamilyAddresses ) { Location updatedAddress = null; if ( familyAddress.LocationIsDirty ) { updatedAddress = new LocationService( rockContext ).Get( familyAddress.Street1, familyAddress.Street2, familyAddress.City, familyAddress.State, familyAddress.Zip ); } GroupLocation groupLocation = null; if ( familyAddress.Id > 0 ) { groupLocation = groupLocationService.Get( familyAddress.Id ); } if ( groupLocation == null ) { groupLocation = new GroupLocation(); groupLocation.GroupId = _family.Id; groupLocationService.Add( groupLocation ); } History.EvaluateChange( familyChanges, "Location Type", groupLocation.GroupLocationTypeValueId.HasValue ? DefinedValueCache.Read( groupLocation.GroupLocationTypeValueId.Value ).Name : string.Empty, familyAddress.LocationTypeName ); groupLocation.GroupLocationTypeValueId = familyAddress.LocationTypeId; History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Mailing", groupLocation.IsMailingLocation.ToString(), familyAddress.IsMailing.ToString() ); groupLocation.IsMailingLocation = familyAddress.IsMailing; History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Map Location", groupLocation.IsMappedLocation.ToString(), familyAddress.IsLocation.ToString() ); groupLocation.IsMappedLocation = familyAddress.IsLocation; if ( updatedAddress != null ) { History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Location", groupLocation.Location != null ? groupLocation.Location.ToString() : "", updatedAddress.ToString() ); groupLocation.Location = updatedAddress; } rockContext.SaveChanges(); // Add the same locations to any new families created by removing an existing family member if ( newFamilies.Any() ) { //reload grouplocation for access to child properties groupLocation = groupLocationService.Get( groupLocation.Id ); foreach ( var newFamily in newFamilies ) { var newFamilyLocation = new GroupLocation(); newFamilyLocation.GroupId = newFamily.Id; newFamilyLocation.LocationId = groupLocation.LocationId; newFamilyLocation.GroupLocationTypeValueId = groupLocation.GroupLocationTypeValueId; newFamilyLocation.IsMailingLocation = groupLocation.IsMailingLocation; newFamilyLocation.IsMappedLocation = groupLocation.IsMappedLocation; groupLocationService.Add( newFamilyLocation ); } rockContext.SaveChanges(); } } foreach ( var fm in _family.Members ) { HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.PersonId, familyChanges, _family.Name, typeof( Group ), _family.Id ); } _family = familyService.Get( _family.Id ); if ( _family.Members.Any( m => m.PersonId == Person.Id ) ) { Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false ); } else { var fm = _family.Members .Where( m => m.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT ) ) && m.Person.Gender == Gender.Male ) .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); if ( fm == null ) { fm = _family.Members .Where( m => m.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT ) ) ) .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); } if ( fm == null ) { fm = _family.Members .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); } if ( fm != null ) { Response.Redirect( string.Format( "~/Person/{0}", fm.PersonId ), false ); } else { Response.Redirect( "~", false ); } } } ); } }
/// <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 { // get groups set to sync RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); var groupsThatSync = groupService.Queryable().Where( g => g.SyncDataViewId != null ).ToList(); foreach ( var syncGroup in groupsThatSync ) { GroupMemberService groupMemberService = new GroupMemberService( rockContext ); var syncSource = new DataViewService( rockContext ).Get( syncGroup.SyncDataViewId.Value ); // ensure this is a person dataview bool isPersonDataSet = syncSource.EntityTypeId == EntityTypeCache.Read( typeof( Rock.Model.Person ) ).Id; if ( isPersonDataSet ) { SortProperty sortById = new SortProperty(); sortById.Property = "Id"; sortById.Direction = System.Web.UI.WebControls.SortDirection.Ascending; List<string> errorMessages = new List<string>(); var sourceItems = syncSource.GetQuery( sortById, 180, out errorMessages ).Select( q => q.Id ).ToList(); var targetItems = groupMemberService.Queryable("Person").Where( gm => gm.GroupId == syncGroup.Id ).ToList(); // delete items from the target not in the source foreach ( var targetItem in targetItems.Where( t => !sourceItems.Contains( t.PersonId ) ) ) { // made a clone of the person as it will be detached when the group member is deleted. Also // saving the delete before the email is sent in case an exception occurs so the user doesn't // get an email everytime the agent runs. Person recipient = (Person)targetItem.Person.Clone(); groupMemberService.Delete( targetItem ); rockContext.SaveChanges(); if ( syncGroup.ExitSystemEmailId.HasValue ) { SendExitEmail( syncGroup.ExitSystemEmailId.Value, recipient, syncGroup ); } } // add items not in target but in the source foreach ( var sourceItem in sourceItems.Where( s => !targetItems.Select( t => t.PersonId ).Contains( s ) ) ) { // add source to target var newGroupMember = new GroupMember { Id = 0 }; newGroupMember.PersonId = sourceItem; newGroupMember.Group = syncGroup; newGroupMember.GroupMemberStatus = GroupMemberStatus.Active; newGroupMember.GroupRoleId = syncGroup.GroupType.DefaultGroupRoleId ?? syncGroup.GroupType.Roles.FirstOrDefault().Id; groupMemberService.Add( newGroupMember ); if ( syncGroup.WelcomeSystemEmailId.HasValue ) { SendWelcomeEmail( syncGroup.WelcomeSystemEmailId.Value, sourceItem, syncGroup, syncGroup.AddUserAccountsDuringSync ?? false ); } } rockContext.SaveChanges(); } } } catch ( System.Exception ex ) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException( ex, context2 ); throw ex; } }
/// <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> /// Handles the Click event of the lbMerge control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void lbMerge_Click( object sender, EventArgs e ) { if ( MergeData.People.Count < 2 ) { nbPeople.Visible = true; return; } bool reconfirmRequired = ( MergeData.People.Select( p => p.Email ).Distinct().Count() > 1 && MergeData.People.Where( p => p.HasLogins ).Any() ); GetValuesSelection(); int? primaryPersonId = null; var oldPhotos = new List<int>(); var rockContext = new RockContext(); rockContext.WrapTransaction( () => { var personService = new PersonService( rockContext ); var userLoginService = new UserLoginService( rockContext ); var groupService = new GroupService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var binaryFileService = new BinaryFileService( rockContext ); var phoneNumberService = new PhoneNumberService( rockContext ); var taggedItemService = new TaggedItemService( rockContext ); Person primaryPerson = personService.Get( MergeData.PrimaryPersonId ?? 0 ); if ( primaryPerson != null ) { primaryPersonId = primaryPerson.Id; var changes = new List<string>(); foreach ( var p in MergeData.People.Where( p => p.Id != primaryPerson.Id ) ) { changes.Add( string.Format( "Merged <span class='field-value'>{0} [ID: {1}]</span> with this record.", p.FullName, p.Id ) ); } // Photo Id int? newPhotoId = MergeData.GetSelectedValue( MergeData.GetProperty( "Photo" ) ).Value.AsIntegerOrNull(); if ( !primaryPerson.PhotoId.Equals( newPhotoId ) ) { changes.Add( "Modified the photo." ); primaryPerson.PhotoId = newPhotoId; } primaryPerson.TitleValueId = GetNewIntValue( "Title", changes ); primaryPerson.FirstName = GetNewStringValue( "FirstName", changes ); primaryPerson.NickName = GetNewStringValue( "NickName", changes ); primaryPerson.MiddleName = GetNewStringValue( "MiddleName", changes ); primaryPerson.LastName = GetNewStringValue( "LastName", changes ); primaryPerson.SuffixValueId = GetNewIntValue( "Suffix", changes ); primaryPerson.RecordTypeValueId = GetNewIntValue( "RecordType", changes ); primaryPerson.RecordStatusValueId = GetNewIntValue( "RecordStatus", changes ); primaryPerson.RecordStatusReasonValueId = GetNewIntValue( "RecordStatusReason", changes ); primaryPerson.ConnectionStatusValueId = GetNewIntValue( "ConnectionStatus", changes ); primaryPerson.IsDeceased = GetNewBoolValue( "Deceased", changes ) ?? false; primaryPerson.Gender = (Gender)GetNewEnumValue( "Gender", typeof( Gender ), changes ); primaryPerson.MaritalStatusValueId = GetNewIntValue( "MaritalStatus", changes ); primaryPerson.SetBirthDate( GetNewDateTimeValue( "BirthDate", changes ) ); primaryPerson.AnniversaryDate = GetNewDateTimeValue( "AnniversaryDate", changes ); primaryPerson.GraduationYear = GetNewIntValue( "GraduationYear", changes ); primaryPerson.Email = GetNewStringValue( "Email", changes ); primaryPerson.IsEmailActive = GetNewBoolValue( "EmailActive", changes ) ?? true; primaryPerson.EmailNote = GetNewStringValue( "EmailNote", changes ); primaryPerson.EmailPreference = (EmailPreference)GetNewEnumValue( "EmailPreference", typeof( EmailPreference ), changes ); primaryPerson.SystemNote = GetNewStringValue( "InactiveReasonNote", changes ); primaryPerson.SystemNote = GetNewStringValue( "SystemNote", changes ); // Update phone numbers var phoneTypes = DefinedTypeCache.Read( Rock.SystemGuid.DefinedType.PERSON_PHONE_TYPE.AsGuid() ).DefinedValues; foreach ( var phoneType in phoneTypes ) { var phoneNumber = primaryPerson.PhoneNumbers.Where( p => p.NumberTypeValueId == phoneType.Id ).FirstOrDefault(); string oldValue = phoneNumber != null ? phoneNumber.Number : string.Empty; string key = "phone_" + phoneType.Id.ToString(); string newValue = GetNewStringValue( key, changes ); bool phoneNumberDeleted = false; if ( !oldValue.Equals( newValue, StringComparison.OrdinalIgnoreCase ) ) { // New phone doesn't match old if ( !string.IsNullOrWhiteSpace( newValue ) ) { // New value exists if ( phoneNumber == null ) { // Old value didn't exist... create new phone record phoneNumber = new PhoneNumber { NumberTypeValueId = phoneType.Id }; primaryPerson.PhoneNumbers.Add( phoneNumber ); } // Update phone number phoneNumber.Number = newValue; } else { // New value doesn't exist if ( phoneNumber != null ) { // old value existed.. delete it primaryPerson.PhoneNumbers.Remove( phoneNumber ); phoneNumberService.Delete( phoneNumber ); phoneNumberDeleted = true; } } } // check to see if IsMessagingEnabled is true for any of the merged people for this number/numbertype if ( phoneNumber != null && !phoneNumberDeleted && !phoneNumber.IsMessagingEnabled ) { var personIds = MergeData.People.Select( a => a.Id ).ToList(); var isMessagingEnabled = phoneNumberService.Queryable().Where( a => personIds.Contains( a.PersonId ) && a.Number == phoneNumber.Number && a.NumberTypeValueId == phoneNumber.NumberTypeValueId ).Any( a => a.IsMessagingEnabled ); if ( isMessagingEnabled ) { phoneNumber.IsMessagingEnabled = true; } } } // Save the new record rockContext.SaveChanges(); // Update the attributes primaryPerson.LoadAttributes( rockContext ); foreach ( var property in MergeData.Properties.Where( p => p.Key.StartsWith( "attr_" ) ) ) { string attributeKey = property.Key.Substring( 5 ); string oldValue = primaryPerson.GetAttributeValue( attributeKey ) ?? string.Empty; string newValue = GetNewStringValue( property.Key, changes ) ?? string.Empty; if ( !oldValue.Equals( newValue ) ) { var attribute = primaryPerson.Attributes[attributeKey]; Rock.Attribute.Helper.SaveAttributeValue( primaryPerson, attribute, newValue, rockContext ); } } HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), primaryPerson.Id, changes ); // Delete the unselected photos string photoKeeper = primaryPerson.PhotoId.HasValue ? primaryPerson.PhotoId.Value.ToString() : string.Empty; foreach ( var photoValue in MergeData.Properties .Where( p => p.Key == "Photo" ) .SelectMany( p => p.Values ) .Where( v => v.Value != "" && v.Value != photoKeeper ) .Select( v => v.Value ) ) { int photoId = 0; if ( int.TryParse( photoValue, out photoId ) ) { var photo = binaryFileService.Get( photoId ); if ( photo != null ) { string errorMessages; if ( binaryFileService.CanDelete( photo, out errorMessages ) ) { binaryFileService.Delete( photo ); } } } } rockContext.SaveChanges(); // Delete merged person's family records and any families that would be empty after merge foreach ( var p in MergeData.People.Where( p => p.Id != primaryPersonId.Value ) ) { // Delete the merged person's phone numbers (we've already updated the primary persons values) foreach ( var phoneNumber in phoneNumberService.GetByPersonId( p.Id ) ) { phoneNumberService.Delete( phoneNumber ); } // If there was more than one email address and user has logins, then set any of the local // logins ( database & AD ) to require a reconfirmation if ( reconfirmRequired ) { foreach ( var login in userLoginService.GetByPersonId( p.Id ) ) { var component = Rock.Security.AuthenticationContainer.GetComponent( login.EntityType.Name ); if ( component != null && !component.RequiresRemoteAuthentication ) { login.IsConfirmed = false; } } } rockContext.SaveChanges(); // Delete the merged person's other family member records and the family if they were the only one in the family Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid(); foreach ( var familyMember in groupMemberService.Queryable().Where( m => m.PersonId == p.Id && m.Group.GroupType.Guid == familyGuid ) ) { groupMemberService.Delete( familyMember ); rockContext.SaveChanges(); // Get the family var family = groupService.Queryable( "Members" ).Where( f => f.Id == familyMember.GroupId ).FirstOrDefault(); if ( !family.Members.Any() ) { // If there are not any other family members, delete the family record. // If theres any people that have this group as a giving group, set it to null (the person being merged should be the only one) foreach ( Person gp in personService.Queryable().Where( g => g.GivingGroupId == family.Id ) ) { gp.GivingGroupId = null; } // save to the database prior to doing groupService.Delete since .Delete quietly might not delete if thinks the Family is used for a GivingGroupId rockContext.SaveChanges(); // Delete the family string errorMessage; if ( groupService.CanDelete( family, out errorMessage ) ) { var oldFamilyChanges = new List<string>(); History.EvaluateChange( oldFamilyChanges, "Family", family.Name, string.Empty ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), primaryPersonId.Value, oldFamilyChanges, family.Name, typeof( Group ), family.Id ); groupService.Delete( family ); rockContext.SaveChanges(); } } } } // Flush any security roles that the merged person's other records were a part of foreach ( var p in MergeData.People.Where( p => p.Id != primaryPersonId.Value ) ) { foreach ( var groupMember in groupMemberService.Queryable().Where( m => m.PersonId == p.Id ) ) { Group group = new GroupService( rockContext ).Get( groupMember.GroupId ); if ( group.IsSecurityRole || group.GroupType.Guid.Equals( Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid() ) ) { Rock.Security.Role.Flush( group.Id ); Rock.Security.Authorization.Flush(); } } } // now that the Merge is complete, the EntitySet can be marked to be deleted by the RockCleanup job var entitySetService = new EntitySetService( rockContext ); var entitySet = entitySetService.Get( MergeData.EntitySetId ); if ( entitySet != null ) { entitySet.ExpireDateTime = RockDateTime.Now.AddMinutes(-1); entitySet.EntitySetPurposeValueId = null; rockContext.SaveChanges(); } } } ); foreach ( var p in MergeData.People.Where( p => p.Id != primaryPersonId.Value ) ) { // Run merge proc to merge all associated data var parms = new Dictionary<string, object>(); parms.Add( "OldId", p.Id ); parms.Add( "NewId", primaryPersonId.Value ); DbService.ExecuteCommand( "spCrm_PersonMerge", CommandType.StoredProcedure, parms ); } NavigateToLinkedPage( "PersonDetailPage", "PersonId", primaryPersonId.Value ); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public virtual void Execute( IJobExecutionContext context ) { JobDataMap dataMap = context.JobDetail.JobDataMap; var groupType = GroupTypeCache.Read( dataMap.GetString( "GroupType" ).AsGuid() ); int attendanceRemindersSent = 0; if ( groupType.TakesAttendance && groupType.SendAttendanceReminder ) { // Get the occurrence dates that apply var dates = new List<DateTime>(); dates.Add( RockDateTime.Today ); try { string[] reminderDays = dataMap.GetString( "SendReminders" ).Split( ',' ); foreach ( string reminderDay in reminderDays ) { if ( reminderDay.Trim() != string.Empty ) { var reminderDate = RockDateTime.Today.AddDays( 0 - Convert.ToInt32( reminderDay ) ); if ( !dates.Contains( reminderDate ) ) { dates.Add( reminderDate ); } } } } catch { } var rockContext = new RockContext(); var groupService = new GroupService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var scheduleService = new ScheduleService( rockContext ); var attendanceService = new AttendanceService( rockContext ); var startDate = dates.Min(); var endDate = dates.Max().AddDays( 1 ); // Find all 'occurrences' for the groups that occur on the affected dates var occurrences = new Dictionary<int, List<DateTime>>(); foreach ( var group in groupService .Queryable( "Schedule" ).AsNoTracking() .Where( g => g.GroupTypeId == groupType.Id && g.IsActive && g.Schedule != null && g.Members.Any( m => m.GroupMemberStatus == GroupMemberStatus.Active && m.GroupRole.IsLeader && m.Person.Email != null && m.Person.Email != "" ) ) ) { // Add the group occurrences.Add( group.Id, new List<DateTime>() ); // Check for a iCal schedule if ( !string.IsNullOrWhiteSpace( group.Schedule.iCalendarContent ) ) { // If schedule has an iCal schedule, get occurrences between first and last dates foreach ( var occurrence in group.Schedule.GetOccurrences( startDate, endDate ) ) { var startTime = occurrence.Period.StartTime.Value; if ( dates.Contains( startTime.Date ) ) { occurrences[group.Id].Add( startTime ); } } } else { // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week if ( group.Schedule.WeeklyDayOfWeek.HasValue ) { foreach ( var date in dates ) { if ( date.DayOfWeek == group.Schedule.WeeklyDayOfWeek.Value ) { var startTime = date; if ( group.Schedule.WeeklyTimeOfDay.HasValue ) { startTime = startTime.Add( group.Schedule.WeeklyTimeOfDay.Value ); } occurrences[group.Id].Add( startTime ); } } } } } // Remove any occurrences during group type exclusion date ranges foreach ( var exclusion in groupType.GroupScheduleExclusions ) { if ( exclusion.Start.HasValue && exclusion.End.HasValue ) { foreach ( var keyVal in occurrences ) { foreach ( var occurrenceDate in keyVal.Value.ToList() ) { if ( occurrenceDate >= exclusion.Start.Value && occurrenceDate < exclusion.End.Value.AddDays( 1 ) ) { keyVal.Value.Remove( occurrenceDate ); } } } } } // Remove any 'occurrenes' that already have attendance data entered foreach ( var occurrence in attendanceService .Queryable().AsNoTracking() .Where( a => a.StartDateTime >= startDate && a.StartDateTime < endDate && occurrences.Keys.Contains( a.GroupId.Value ) && a.ScheduleId.HasValue ) .Select( a => new { GroupId = a.GroupId.Value, a.StartDateTime } ) .Distinct() .ToList() ) { occurrences[occurrence.GroupId].RemoveAll( d => d.Date == occurrence.StartDateTime.Date ); } // Get the groups that have occurrences var groupIds = occurrences.Where( o => o.Value.Any() ).Select( o => o.Key ).ToList(); // Get the leaders of those groups var leaders = groupMemberService .Queryable( "Group,Person" ).AsNoTracking() .Where( m => groupIds.Contains( m.GroupId ) && m.GroupMemberStatus == GroupMemberStatus.Active && m.GroupRole.IsLeader && m.Person.Email != null && m.Person.Email != "" ) .ToList(); // Loop through the leaders foreach ( var leader in leaders ) { foreach ( var group in occurrences.Where( o => o.Key == leader.GroupId ) ) { var mergeObjects = Rock.Lava.LavaHelper.GetCommonMergeFields( null, leader.Person ); mergeObjects.Add( "Person", leader.Person ); mergeObjects.Add( "Group", leader.Group ); mergeObjects.Add( "Occurrence", group.Value.Max() ); var recipients = new List<RecipientData>(); recipients.Add( new RecipientData( leader.Person.Email, mergeObjects ) ); Email.Send( dataMap.GetString( "SystemEmail" ).AsGuid(), recipients ); attendanceRemindersSent++; } } } context.Result = string.Format( "{0} attendance reminders sent", attendanceRemindersSent ); }
/// <summary> /// Displays the edit group panel. /// </summary> private void DisplayEditGroup() { this.IsEditingGroup = true; if ( _groupId != -1 ) { RockContext rockContext = new RockContext(); GroupService groupService = new GroupService( rockContext ); var qry = groupService .Queryable( "GroupLocations,GroupType,Schedule" ) .Where( g => g.Id == _groupId ); var group = qry.FirstOrDefault(); if ( group.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { tbName.Text = group.Name; tbDescription.Text = group.Description; cbIsActive.Checked = group.IsActive; if ( ( group.GroupType.AllowedScheduleTypes & ScheduleType.Weekly ) == ScheduleType.Weekly ) { pnlSchedule.Visible = group.Schedule == null || group.Schedule.ScheduleType == ScheduleType.Weekly; if ( group.Schedule != null ) { dowWeekly.SelectedDayOfWeek = group.Schedule.WeeklyDayOfWeek; timeWeekly.SelectedTime = group.Schedule.WeeklyTimeOfDay; } else { dowWeekly.SelectedDayOfWeek = null; timeWeekly.SelectedTime = null; } } else { pnlSchedule.Visible = false; } group.LoadAttributes(); phAttributes.Controls.Clear(); Rock.Attribute.Helper.AddEditControls( group, phAttributes, true, BlockValidationGroup ); // enable editing location pnlGroupEditLocations.Visible = GetAttributeValue( "EnableLocationEdit" ).AsBoolean(); if ( GetAttributeValue( "EnableLocationEdit" ).AsBoolean() ) { ConfigureGroupLocationControls( group ); // set location tabs rptLocationTypes.DataSource = _tabs; rptLocationTypes.DataBind(); } } else { lContent.Text = "<div class='alert alert-warning'>You do not have permission to edit this group.</div>"; } } else { lContent.Text = "<div class='alert alert-warning'>No group was available from the querystring.</div>"; } }