/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute( IJobExecutionContext context ) { var rockContext = new RockContext(); var groupRequirementService = new GroupRequirementService( rockContext ); var groupMemberRequirementService = new GroupMemberRequirementService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); // we only need to consider group requirements that are based on a DataView or SQL var groupRequirementQry = groupRequirementService.Queryable() .Where( a => a.GroupRequirementType.RequirementCheckType != RequirementCheckType.Manual ) .AsNoTracking(); var calculationExceptions = new List<Exception>(); foreach ( var groupRequirement in groupRequirementQry.Include( i => i.GroupRequirementType ).AsNoTracking().ToList() ) { try { var groupMemberQry = groupMemberService.Queryable().Where( a => a.GroupId == groupRequirement.GroupId ).AsNoTracking(); var personQry = groupMemberQry.Select( a => a.Person ); var currentDateTime = RockDateTime.Now; var expireDaysCount = groupRequirement.GroupRequirementType.ExpireInDays.Value; var qryGroupMemberRequirementsAlreadyOK = groupMemberRequirementService.Queryable().Where( a => a.GroupRequirementId == groupRequirement.Id ); if ( groupRequirement.GroupRequirementType.CanExpire && groupRequirement.GroupRequirementType.ExpireInDays.HasValue ) { // Expirable: don't recalculate members that already met the requirement within the expiredays qryGroupMemberRequirementsAlreadyOK = qryGroupMemberRequirementsAlreadyOK.Where( a => a.RequirementMetDateTime.HasValue && SqlFunctions.DateDiff( "day", a.RequirementMetDateTime, currentDateTime ) < expireDaysCount ); } else { // No Expiration: don't recalculate members that already met the requirement qryGroupMemberRequirementsAlreadyOK = qryGroupMemberRequirementsAlreadyOK.Where( a => a.RequirementMetDateTime.HasValue ); } personQry = personQry.Where( a => !qryGroupMemberRequirementsAlreadyOK.Any( r => r.GroupMember.PersonId == a.Id ) ); var results = groupRequirement.PersonQueryableMeetsGroupRequirement( rockContext, personQry, groupRequirement.GroupRoleId ).ToList(); foreach ( var result in results ) { // use a fresh rockContext per Update so that ChangeTracker doesn't get bogged down var rockContextUpdate = new RockContext(); groupRequirement.UpdateGroupMemberRequirementResult( rockContextUpdate, result.PersonId, result.MeetsGroupRequirement ); rockContextUpdate.SaveChanges(); } } catch ( Exception ex ) { calculationExceptions.Add( new Exception( string.Format( "Exception when calculating group requirement: ", groupRequirement ), ex ) ); } } if ( calculationExceptions.Any() ) { throw new AggregateException( "One or more group requirement calculations failed ", calculationExceptions ); } }
/// <summary> /// Returns a list of matching people /// </summary> /// <param name="searchterm"></param> /// <returns></returns> public override IQueryable<string> Search( string searchterm ) { Guid groupTypefamilyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); Guid homeAddressTypeGuid = new Guid( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME ); var homeAddressTypeValueId = Rock.Web.Cache.DefinedValueCache.Read( homeAddressTypeGuid ).Id; var service = new GroupMemberService( new RockContext() ); return service.Queryable() .Where( m => m.Group.GroupType.Guid == groupTypefamilyGuid ) .SelectMany( g => g.Group.GroupLocations ) .Where( gl => gl.GroupLocationTypeValueId == homeAddressTypeValueId && gl.Location.Street1.Contains(searchterm) ) .Select( gl => gl.Location.Street1) .Distinct(); }
public GroupOfTypeResult GetInGroupOfType(int personId, Guid groupTypeId) { GroupOfTypeResult result = new GroupOfTypeResult(); result.PersonId = personId; result.PersonInGroup = false; result.GroupList = new List<GroupSummary>(); // get person info Person person = new PersonService( (Rock.Data.RockContext)Service.Context ).Get( personId ); if (person != null) { result.NickName = person.NickName; result.LastName = person.LastName; } // get group type info GroupType groupType = new GroupTypeService( (Rock.Data.RockContext)Service.Context ).Get( groupTypeId ); if (groupType != null) { result.GroupTypeName = groupType.Name; result.GroupTypeIconCss = groupType.IconCssClass; result.GroupTypeId = groupType.Id; } // determine if person is in this type of group GroupMemberService groupMemberService = new GroupMemberService( (Rock.Data.RockContext)Service.Context ); IQueryable<GroupMember> groupMembershipsQuery = groupMemberService.Queryable("Person,GroupRole,Group") .Where(t => t.Group.GroupType.Guid == groupTypeId && t.PersonId == personId ) .OrderBy(g => g.GroupRole.Order); foreach (GroupMember member in groupMembershipsQuery) { result.PersonInGroup = true; GroupSummary group = new GroupSummary(); group.GroupName = member.Group.Name; group.GroupId = member.Group.Id; group.RoleName = member.GroupRole.Name; result.GroupList.Add(group); } return result; }
/// <summary> /// The groups of a particular type that current person belongs to /// </summary> /// <returns></returns> protected IEnumerable<Group> PersonGroups( int groupTypeId ) { string itemKey = "RockGroups:" + groupTypeId.ToString(); var groups = Context.Items[itemKey] as IEnumerable<Group>; if ( groups != null ) return groups; if ( Person == null ) return null; var service = new GroupMemberService(); groups = service.Queryable() .Where( m => m.PersonId == Person.Id && m.Group.GroupTypeId == groupTypeId ) .Select( m => m.Group ) .OrderByDescending( g => g.Name ); Context.Items.Add( itemKey, groups ); return groups; }
/// <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 ); } } } ); } }
private Person GetPersonOrBusiness( Person person ) { if ( person != null && phGiveAsOption.Visible && !tglGiveAsOption.Checked ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); var groupService = new GroupService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); Group familyGroup = null; Person business = null; int? businessId = cblBusiness.SelectedValueAsInt(); if ( businessId.HasValue ) { business = personService.Get( businessId.Value ); } if ( business == null ) { DefinedValueCache dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() ); DefinedValueCache dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() ); // Create Person business = new Person(); business.LastName = txtLastName.Text; business.IsEmailActive = true; business.EmailPreference = EmailPreference.EmailAllowed; business.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_BUSINESS.AsGuid() ).Id; if ( dvcConnectionStatus != null ) { business.ConnectionStatusValueId = dvcConnectionStatus.Id; } if ( dvcRecordStatus != null ) { business.RecordStatusValueId = dvcRecordStatus.Id; } // Create Person/Family familyGroup = PersonService.SaveNewPerson( business, rockContext, null, false ); // Get the relationship roles to use var knownRelationshipGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid() ); int businessContactRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); int businessRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); int ownerRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); if ( ownerRoleId > 0 && businessContactRoleId > 0 && businessRoleId > 0 ) { // get the known relationship group of the business contact // add the business as a group member of that group using the group role of GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS var contactKnownRelationshipGroup = groupMemberService.Queryable() .Where( g => g.GroupRoleId == ownerRoleId && g.PersonId == person.Id ) .Select( g => g.Group ) .FirstOrDefault(); if ( contactKnownRelationshipGroup == null ) { // In some cases person may not yet have a know relationship group type contactKnownRelationshipGroup = new Group(); groupService.Add( contactKnownRelationshipGroup ); contactKnownRelationshipGroup.Name = "Known Relationship"; contactKnownRelationshipGroup.GroupTypeId = knownRelationshipGroupType.Id; var ownerMember = new GroupMember(); ownerMember.PersonId = person.Id; ownerMember.GroupRoleId = ownerRoleId; contactKnownRelationshipGroup.Members.Add( ownerMember ); } var groupMember = new GroupMember(); groupMember.PersonId = business.Id; groupMember.GroupRoleId = businessRoleId; contactKnownRelationshipGroup.Members.Add( groupMember ); // get the known relationship group of the business // add the business contact as a group member of that group using the group role of GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT var businessKnownRelationshipGroup = groupMemberService.Queryable() .Where( g => g.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER ) ) && g.PersonId == business.Id ) .Select( g => g.Group ) .FirstOrDefault(); if ( businessKnownRelationshipGroup == null ) { // In some cases business may not yet have a know relationship group type businessKnownRelationshipGroup = new Group(); groupService.Add( businessKnownRelationshipGroup ); businessKnownRelationshipGroup.Name = "Known Relationship"; businessKnownRelationshipGroup.GroupTypeId = knownRelationshipGroupType.Id; var ownerMember = new GroupMember(); ownerMember.PersonId = business.Id; ownerMember.GroupRoleId = ownerRoleId; businessKnownRelationshipGroup.Members.Add( ownerMember ); } var businessGroupMember = new GroupMember(); businessGroupMember.PersonId = person.Id; businessGroupMember.GroupRoleId = businessContactRoleId; businessKnownRelationshipGroup.Members.Add( businessGroupMember ); rockContext.SaveChanges(); } } business.LastName = txtBusinessName.Text; business.Email = txtEmail.Text; if ( GetAttributeValue( "DisplayPhone" ).AsBooleanOrNull() ?? false ) { var numberTypeId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK ) ).Id; var phone = business.PhoneNumbers.FirstOrDefault( p => p.NumberTypeValueId == numberTypeId ); if ( phone == null ) { phone = new PhoneNumber(); business.PhoneNumbers.Add( phone ); phone.NumberTypeValueId = numberTypeId; } phone.CountryCode = PhoneNumber.CleanNumber( pnbPhone.CountryCode ); phone.Number = PhoneNumber.CleanNumber( pnbPhone.Number ); } if ( familyGroup == null ) { var groupLocationService = new GroupLocationService( rockContext ); if ( GroupLocationId.HasValue ) { familyGroup = groupLocationService.Queryable() .Where( gl => gl.Id == GroupLocationId.Value ) .Select( gl => gl.Group ) .FirstOrDefault(); } else { familyGroup = personService.GetFamilies( business.Id ).FirstOrDefault(); } } rockContext.SaveChanges(); if ( familyGroup != null ) { GroupService.AddNewGroupAddress( rockContext, familyGroup, Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_WORK, acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country, false ); } return business; } return person; }
/// <summary> /// Binds the group members grid. /// </summary> protected void ShowDetails() { bool existingOccurrence = _occurrence != null; if ( !existingOccurrence && !_allowAdd ) { nbNotice.Heading = "No Occurrences"; nbNotice.Text = "<p>There are currently not any active occurrences for selected group to take attendance for.</p>"; nbNotice.NotificationBoxType = NotificationBoxType.Warning; nbNotice.Visible = true; pnlDetails.Visible = false; } else { if ( existingOccurrence ) { lOccurrenceDate.Visible = _occurrence.ScheduleId.HasValue; lOccurrenceDate.Text = _occurrence.Date.ToShortDateString(); dpOccurrenceDate.Visible = !_occurrence.ScheduleId.HasValue; dpOccurrenceDate.SelectedDate = _occurrence.Date; if ( _occurrence.LocationId.HasValue ) { lLocation.Visible = true; lLocation.Text = new LocationService( _rockContext ).GetPath( _occurrence.LocationId.Value ); } else { lLocation.Visible = false; } ddlLocation.Visible = false; lSchedule.Visible = !string.IsNullOrWhiteSpace( _occurrence.ScheduleName ); lSchedule.Text = _occurrence.ScheduleName; ddlSchedule.Visible = false; } else { lOccurrenceDate.Visible = false; dpOccurrenceDate.Visible = true; dpOccurrenceDate.SelectedDate = RockDateTime.Today; int? locationId = PageParameter( "LocationId" ).AsIntegerOrNull(); if ( locationId.HasValue ) { lLocation.Visible = true; lLocation.Text = new LocationService( _rockContext ).GetPath( locationId.Value ); ddlLocation.Visible = false; Schedule schedule = null; int? scheduleId = PageParameter( "ScheduleId" ).AsIntegerOrNull(); if ( scheduleId.HasValue ) { schedule = new ScheduleService( _rockContext ).Get( scheduleId.Value ); } if ( schedule != null ) { lSchedule.Visible = true; lSchedule.Text = schedule.Name; ddlSchedule.Visible = false; } else { BindSchedules( locationId.Value ); lSchedule.Visible = false; ddlSchedule.Visible = ddlSchedule.Items.Count > 1; } } else { lLocation.Visible = false; ddlLocation.Visible = ddlLocation.Items.Count > 1; lSchedule.Visible = false; ddlSchedule.Visible = ddlSchedule.Items.Count > 1; } } lMembers.Text = _group.GroupType.GroupMemberTerm.Pluralize(); lPendingMembers.Text = "Pending " + lMembers.Text; List<int> attendedIds = new List<int>(); // Load the attendance for the selected occurrence if ( existingOccurrence ) { cbDidNotMeet.Checked = _occurrence.DidNotOccur; // Get the list of people who attended attendedIds = new ScheduleService( _rockContext ).GetAttendance( _group, _occurrence ) .Where( a => a.DidAttend.HasValue && a.DidAttend.Value ) .Select( a => a.PersonAlias.PersonId ) .Distinct() .ToList(); } ppAddPerson.Visible = GetAttributeValue( "AllowAddingPerson" ).AsBoolean(); // Get the group members var groupMemberService = new GroupMemberService( _rockContext ); // Add any existing active members not on that list var unattendedIds = groupMemberService .Queryable().AsNoTracking() .Where( m => m.GroupId == _group.Id && m.GroupMemberStatus == GroupMemberStatus.Active && !attendedIds.Contains( m.PersonId ) ) .Select( m => m.PersonId ) .ToList(); string template = GetAttributeValue( "LavaTemplate" ); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); // Bind the attendance roster _attendees = new PersonService( _rockContext ) .Queryable().AsNoTracking() .Where( p => attendedIds.Contains( p.Id ) || unattendedIds.Contains( p.Id ) ) .ToList() .Select( p => new GroupAttendanceAttendee() { PersonId = p.Id, NickName = p.NickName, LastName = p.LastName, Attended = attendedIds.Contains( p.Id ), CampusIds = p.GetCampusIds(), MergedTemplate = template.ResolveMergeFields( mergeFields.Union( new Dictionary<string, object>() { { "Person", p } } ).ToDictionary( x => x.Key, x => x.Value ) ) } ) .ToList(); BindAttendees(); // Bind the pending members var pendingMembers = groupMemberService .Queryable().AsNoTracking() .Where( m => m.GroupId == _group.Id && m.GroupMemberStatus == GroupMemberStatus.Pending ) .OrderBy( m => m.Person.LastName ) .ThenBy( m => m.Person.NickName ) .Select( m => new { Id = m.PersonId, FullName = m.Person.NickName + " " + m.Person.LastName } ) .ToList(); pnlPendingMembers.Visible = pendingMembers.Any(); lvPendingMembers.DataSource = pendingMembers; lvPendingMembers.DataBind(); } }
/// <summary> /// Gets the expression. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override Expression GetExpression( Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection ) { var rockContext = (RockContext)serviceInstance.Context; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 1 ) { Campus campus = new CampusService( rockContext ).Get( selectionValues[0].AsGuid() ); if ( campus == null ) { return null; } GroupMemberService groupMemberService = new GroupMemberService( rockContext ); var groupMemberServiceQry = groupMemberService.Queryable() .Where( xx => xx.Group.GroupType.Guid == new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ) ) .Where( xx => xx.Group.CampusId == campus.Id ); var qry = new PersonService( rockContext ).Queryable() .Where( p => groupMemberServiceQry.Any( xx => xx.PersonId == p.Id ) ); Expression extractedFilterExpression = FilterExpressionExtractor.Extract<Rock.Model.Person>( qry, parameterExpression, "p" ); return extractedFilterExpression; } return null; }
public List<GroupAndLeaderInfo> GetGeofencingGroups( int personId, Guid groupTypeGuid ) { var rockContext = (Rock.Data.RockContext)Service.Context; var groupMemberService = new GroupMemberService( rockContext ); var groups = new GroupService( rockContext ).GetGeofencingGroups( personId, groupTypeGuid ).AsNoTracking(); var result = new List<GroupAndLeaderInfo>(); foreach ( var group in groups.OrderBy( g => g.Name ) ) { var info = new GroupAndLeaderInfo(); info.GroupName = group.Name.Trim(); info.LeaderNames = groupMemberService .Queryable().AsNoTracking() .Where( m => m.GroupId == group.Id && m.GroupRole.IsLeader ) .Select( m => m.Person.NickName + " " + m.Person.LastName ) .ToList() .AsDelimited(", "); result.Add(info); } return result; }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using ( var rockContext = new RockContext() ) { var relationshipGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid() ); if ( relationshipGroupType != null ) { var ownerRole = relationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid() ) ) .FirstOrDefault(); var friendRole = relationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_FACEBOOK_FRIEND.AsGuid() ) ) .FirstOrDefault(); if ( ownerRole != null && friendRole != null ) { var userLoginService = new UserLoginService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); // Convert list of facebook ids into list of usernames var friendUserNames = FacebookIds.Select( i => "FACEBOOK_" + i ).ToList(); // Get the list of person ids associated with friends usernames var friendPersonIds = userLoginService.Queryable() .Where( l => l.PersonId.HasValue && l.PersonId != PersonId && friendUserNames.Contains( l.UserName ) ) .Select( l => l.PersonId.Value ) .Distinct() .ToList(); // Get the person's group id var personGroup = groupMemberService.Queryable() .Where( m => m.PersonId == PersonId && m.GroupRoleId == ownerRole.Id && m.Group.GroupTypeId == relationshipGroupType.Id ) .Select( m => m.Group ) .FirstOrDefault(); // Verify that a 'known relationships' type group existed for the person, if not create it if ( personGroup == null ) { var groupMember = new GroupMember(); groupMember.PersonId = PersonId; groupMember.GroupRoleId = ownerRole.Id; personGroup = new Group(); personGroup.Name = relationshipGroupType.Name; personGroup.GroupTypeId = relationshipGroupType.Id; personGroup.Members.Add( groupMember ); var groupService = new GroupService( rockContext ); groupService.Add( personGroup ); rockContext.SaveChanges(); } // Get the person's relationship group id var personGroupId = personGroup.Id; // Get all of the friend's relationship group ids var friendGroupIds = groupMemberService.Queryable() .Where( m => m.Group.GroupTypeId == relationshipGroupType.Id && m.GroupRoleId == ownerRole.Id && friendPersonIds.Contains( m.PersonId ) ) .Select( m => m.GroupId ) .Distinct() .ToList(); // Find all the existing friend relationships in Rock ( both directions ) var existingFriends = groupMemberService.Queryable() .Where( m => m.Group.GroupTypeId == relationshipGroupType.Id && ( ( friendPersonIds.Contains( m.PersonId ) && m.GroupId == personGroupId ) || ( m.PersonId == PersonId && m.GroupId != personGroupId ) ) ) .ToList(); // Create temp group members for current Facebook friends var currentFriends = new List<GroupMember>(); // ( Person > Friend ) foreach ( int personId in friendPersonIds ) { var groupMember = new GroupMember(); groupMember.GroupId = personGroupId; groupMember.PersonId = personId; groupMember.GroupRoleId = friendRole.Id; groupMember.GroupMemberStatus = GroupMemberStatus.Active; currentFriends.Add( groupMember ); } // ( Friend > Person ) foreach ( int familyId in friendGroupIds ) { var groupMember = new GroupMember(); groupMember.GroupId = familyId; groupMember.PersonId = PersonId; groupMember.GroupRoleId = friendRole.Id; groupMember.GroupMemberStatus = GroupMemberStatus.Active; currentFriends.Add( groupMember ); } // Add any current friends that do not exist in Rock yet foreach ( var groupMember in currentFriends .Where( f => !existingFriends.Any( e => e.IsEqualTo( f ) ) ) ) { groupMemberService.Add( groupMember ); } // Delete any existing friends that are no longer facebook friends foreach ( var groupMember in existingFriends .Where( f => !currentFriends.Any( e => e.IsEqualTo( f ) ) ) ) { groupMemberService.Delete( groupMember ); } rockContext.SaveChanges(); } } } }
/// <summary> /// Gets the values column header. /// </summary> /// <param name="personId">The person identifier.</param> /// <returns></returns> private string GetValuesColumnHeader( int personId ) { Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); var groupMemberService = new GroupMemberService( new RockContext() ); var families = groupMemberService.Queryable() .Where( m => m.PersonId == personId && m.Group.GroupType.Guid == familyGuid ) .Select( m => m.Group ) .Distinct(); StringBuilder sbHeaderData = new StringBuilder(); foreach ( var family in families ) { sbHeaderData.Append( "<div class='merge-heading-family'>" ); var nickNames = groupMemberService.Queryable( "Person" ) .Where( m => m.GroupId == family.Id ) .OrderBy( m => m.GroupRole.Order ) .ThenBy( m => m.Person.BirthDate ?? DateTime.MinValue ) .ThenByDescending( m => m.Person.Gender ) .Select( m => m.Person.NickName ) .ToList(); if ( nickNames.Any() ) { sbHeaderData.AppendFormat( "{0} ({1})", family.Name, nickNames.AsDelimited( ", " ) ); } else { sbHeaderData.Append( family.Name ); } bool showType = family.GroupLocations.Count() > 1; foreach ( var loc in family.GroupLocations ) { sbHeaderData.AppendFormat( " <br><span>{0}{1}</span>", loc.Location.ToStringSafe(), ( showType ? " (" + loc.GroupLocationTypeValue.Value + ")" : "" ) ); } sbHeaderData.Append( "</div>" ); } return sbHeaderData.ToString(); }
/// <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> /// 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, object serviceInstance, Expression parameterExpression, string selection ) { string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 2 ) { GroupMemberService groupMemberService = new GroupMemberService(); int groupId = selectionValues[0].AsInteger() ?? 0; var groupMemberServiceQry = groupMemberService.Queryable().Where( xx => xx.GroupId == groupId ); var groupRoleIds = selectionValues[1].Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).Select( n => int.Parse( n ) ).ToList(); if ( groupRoleIds.Count() > 0 ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupRoleIds.Contains(xx.GroupRoleId) ); } var qry = new Rock.Data.Service<Rock.Model.Person>().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> /// 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> /// Groups the members not meeting requirements. /// </summary> /// <param name="groupId">The group identifier.</param> /// <param name="includeWarnings">if set to <c>true</c> [include warnings].</param> /// <param name="includeInactive">if set to <c>true</c> [include inactive].</param> /// <returns></returns> public Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> > GroupMembersNotMeetingRequirements(int groupId, bool includeWarnings, bool includeInactive = false) { Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> > results = new Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> >(); var rockContext = this.Context as RockContext; var groupRequirementService = new GroupRequirementService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var groupMemberRequirementService = new GroupMemberRequirementService(rockContext); var qryGroupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId == groupId); bool hasGroupRequirements = qryGroupRequirements.Any(); if (!hasGroupRequirements) { // if no group requirements, then there are no members that don't meet the requirements, so return an empty dictionary return(new Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> >()); } var qryGroupMembers = groupMemberService.Queryable().Where(a => a.GroupId == groupId); var qryGroupMemberRequirements = groupMemberRequirementService.Queryable().Where(a => a.GroupMember.GroupId == groupId); if (!includeInactive) { qryGroupMembers = qryGroupMembers.Where(a => a.GroupMemberStatus == GroupMemberStatus.Active); } // get a list of group member ids that don't meet all the requirements IQueryable <int> qryGroupMemberIdsThatLackGroupRequirements = qryGroupMembers.Where( a => !qryGroupRequirements.Select(x => x.Id).All( r => a.GroupMemberRequirements.Where(mr => mr.RequirementMetDateTime.HasValue).Select(x => x.GroupRequirementId).Contains(r))).Select(a => a.Id); IQueryable <GroupMember> qryMembersWithIssues; if (includeWarnings) { IQueryable <int> qryGroupMemberIdsWithRequirementWarnings = qryGroupMemberRequirements.Where(a => a.RequirementWarningDateTime != null || a.RequirementFailDateTime != null).Select(a => a.GroupMemberId).Distinct(); qryMembersWithIssues = qryGroupMembers.Where(a => qryGroupMemberIdsThatLackGroupRequirements.Contains(a.Id) || qryGroupMemberIdsWithRequirementWarnings.Contains(a.Id)); } else { qryMembersWithIssues = qryGroupMembers.Where(a => qryGroupMemberIdsThatLackGroupRequirements.Contains(a.Id)); } var qry = qryMembersWithIssues.Select(a => new { GroupMember = a, GroupRequirementStatuses = qryGroupMemberRequirements.Where(x => x.GroupMemberId == a.Id) }); var currentDateTime = RockDateTime.Now; foreach (var groupMemberWithIssues in qry) { Dictionary <PersonGroupRequirementStatus, DateTime> statuses = new Dictionary <PersonGroupRequirementStatus, DateTime>(); // populate where the status is known foreach (var requirementStatus in groupMemberWithIssues.GroupRequirementStatuses) { PersonGroupRequirementStatus status = new PersonGroupRequirementStatus(); status.GroupRequirement = requirementStatus.GroupRequirement; status.PersonId = groupMemberWithIssues.GroupMember.PersonId; DateTime occuranceDate = new DateTime(); if (requirementStatus.RequirementMetDateTime == null) { status.MeetsGroupRequirement = MeetsGroupRequirement.NotMet; occuranceDate = requirementStatus.RequirementFailDateTime ?? currentDateTime; } else if (requirementStatus.RequirementWarningDateTime.HasValue) { status.MeetsGroupRequirement = MeetsGroupRequirement.MeetsWithWarning; occuranceDate = requirementStatus.RequirementWarningDateTime.Value; } else { status.MeetsGroupRequirement = MeetsGroupRequirement.Meets; occuranceDate = requirementStatus.RequirementMetDateTime.Value; } statuses.Add(status, occuranceDate); } // also add any groupRequirements that they don't have statuses for (and therefore haven't met) foreach (var groupRequirement in qryGroupRequirements) { if (!statuses.Any(x => x.Key.GroupRequirement.Id == groupRequirement.Id)) { PersonGroupRequirementStatus status = new PersonGroupRequirementStatus(); status.GroupRequirement = groupRequirement; status.PersonId = groupMemberWithIssues.GroupMember.PersonId; status.MeetsGroupRequirement = MeetsGroupRequirement.NotMet; statuses.Add(status, currentDateTime); } } var statusesWithIssues = statuses.Where(a => a.Key.MeetsGroupRequirement != MeetsGroupRequirement.Meets).ToDictionary(k => k.Key, v => v.Value); if (statusesWithIssues.Any()) { results.Add(groupMemberWithIssues.GroupMember, statusesWithIssues); } } return(results); }
/// <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 ); int groupTypeId = 0; Guid groupTypeGuid = selectionValues[0].AsGuid(); var groupType = new GroupTypeService( (RockContext)serviceInstance.Context ).Get( groupTypeGuid ); if ( groupType != null ) { groupTypeId = groupType.Id; } var groupMemberServiceQry = groupMemberService.Queryable().Where( xx => xx.Group.GroupTypeId == groupTypeId ); var groupRoleGuids = selectionValues[1].Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).Select( n => n.AsGuid() ).ToList(); if ( groupRoleGuids.Count() > 0 ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupRoleGuids.Contains( xx.GroupRole.Guid ) ); } GroupMemberStatus? groupMemberStatus = null; if ( selectionValues.Length >= 3 ) { groupMemberStatus = selectionValues[2].ConvertToEnumOrNull<GroupMemberStatus>(); } if ( groupMemberStatus.HasValue ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => xx.GroupMemberStatus == groupMemberStatus.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> /// Adds a KnownRelationship record between the two supplied Guids with the given 'is' relationship type: /// /// Role / inverse Role /// ================================ /// step-parent / step-child /// grandparent / grandchild /// previous-spouse / previous-spouse /// can-check-in / allow-check-in-by /// parent / child /// sibling / sibling /// invited / invited-by /// related / related /// /// ...for xml such as: /// <relationships> /// <relationship a="Ben" personGuid="3C402382-3BD2-4337-A996-9E62F1BAB09D" /// has="step-parent" forGuid="3D7F6605-3666-4AB5-9F4E-D7FEBF93278E" name="Brian" /> /// </relationships> /// /// </summary> /// <param name="elemRelationships"></param> private void AddRelationships( XElement elemRelationships, RockContext rockContext ) { if ( elemRelationships == null ) { return; } Guid ownerRoleGuid = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid(); Guid knownRelationshipsGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid(); var memberService = new GroupMemberService( rockContext ); var groupTypeRoles = new GroupTypeRoleService( rockContext ).Queryable( "GroupType" ) .Where( r => r.GroupType.Guid == knownRelationshipsGroupTypeGuid ).ToList(); //// We have to create (or fetch existing) two groups for each relationship, adding the //// other person as a member of that group with the appropriate GroupTypeRole (GTR): //// * a group with person as owner (GTR) and forPerson as type/role (GTR) //// * a group with forPerson as owner (GTR) and person as inverse-type/role (GTR) foreach ( var elemRelationship in elemRelationships.Elements( "relationship" ) ) { // skip any illegally formatted items if ( elemRelationship.Attribute( "personGuid" ) == null || elemRelationship.Attribute( "forGuid" ) == null || elemRelationship.Attribute( "has" ) == null ) { continue; } Guid personGuid = elemRelationship.Attribute( "personGuid" ).Value.Trim().AsGuid(); Guid forGuid = elemRelationship.Attribute( "forGuid" ).Value.Trim().AsGuid(); int ownerPersonId = _peopleDictionary[personGuid]; int forPersonId = _peopleDictionary[forGuid]; string relationshipType = elemRelationship.Attribute( "has" ).Value.Trim(); int roleId = -1; switch ( relationshipType ) { case "step-parent": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_STEP_PARENT.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "step-child": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_STEP_CHILD.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "can-check-in": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_CAN_CHECK_IN.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "allow-check-in-by": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_ALLOW_CHECK_IN_BY.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "grandparent": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_GRANDPARENT.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "grandchild": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_GRANDCHILD.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "invited": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_INVITED.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "invited-by": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_INVITED_BY.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "previous-spouse": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_PREVIOUS_SPOUSE.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "sibling": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_SIBLING.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "parent": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_PARENT.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "child": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_CHILD.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; case "related": roleId = groupTypeRoles.Where( r => r.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_IMPLIED_RELATIONSHIPS_RELATED.AsGuid() ) .Select( r => r.Id ).FirstOrDefault(); break; default: //// throw new NotSupportedException( string.Format( "unknown relationship type {0}", elemRelationship.Attribute( "has" ).Value ) ); // just skip unknown relationship types continue; } // find the person's KnownRelationship "owner" group var knownRelationshipGroup = memberService.Queryable() .Where( m => m.PersonId == ownerPersonId && m.GroupRole.Guid == ownerRoleGuid ) .Select( m => m.Group ) .FirstOrDefault(); // create it if it does not yet exist if ( knownRelationshipGroup == null ) { var ownerRole = new GroupTypeRoleService( rockContext ).Get( ownerRoleGuid ); if ( ownerRole != null && ownerRole.GroupTypeId.HasValue ) { var ownerGroupMember = new GroupMember(); ownerGroupMember.PersonId = ownerPersonId; ownerGroupMember.GroupRoleId = ownerRole.Id; knownRelationshipGroup = new Group(); knownRelationshipGroup.Name = ownerRole.GroupType.Name; knownRelationshipGroup.GroupTypeId = ownerRole.GroupTypeId.Value; knownRelationshipGroup.Members.Add( ownerGroupMember ); var groupService = new GroupService( rockContext ); groupService.Add( knownRelationshipGroup ); //rockContext.ChangeTracker.DetectChanges(); rockContext.SaveChanges( disablePrePostProcessing: true ); knownRelationshipGroup = groupService.Get( knownRelationshipGroup.Id ); } } // Now find (and add if not found) the forPerson as a member with the "has" role-type var groupMember = memberService.Queryable() .Where( m => m.GroupId == knownRelationshipGroup.Id && m.PersonId == forPersonId && m.GroupRoleId == roleId ) .FirstOrDefault(); if ( groupMember == null ) { groupMember = new GroupMember() { GroupId = knownRelationshipGroup.Id, PersonId = forPersonId, GroupRoleId = roleId, }; rockContext.GroupMembers.Add( groupMember ); } // Now create thee inverse relationship. // // (NOTE: Don't panic if your VS tooling complains that there is // an unused variable here. There is no need to do anything with the // inverseGroupMember relationship because it was already added to the // context. All we have to do below is save the changes to the context // when we're ready.) var inverseGroupMember = memberService.GetInverseRelationship( groupMember, createGroup: true ); } }
private void CreateControls( bool setSelection ) { // Load all the attribute controls attributeControls.Clear(); pnlAttributes.Controls.Clear(); phDuplicates.Controls.Clear(); var rockContext = new RockContext(); var attributeService = new AttributeService( rockContext ); var locationService = new LocationService( rockContext ); foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues( false ) ) { Guid guid = Guid.Empty; if ( Guid.TryParse( categoryGuid, out guid ) ) { var category = CategoryCache.Read( guid ); if ( category != null ) { var attributeControl = new NewGroupAttributes(); attributeControl.ClearRows(); pnlAttributes.Controls.Add( attributeControl ); attributeControls.Add( attributeControl ); attributeControl.ID = "groupAttributes_" + category.Id.ToString(); attributeControl.CategoryId = category.Id; foreach ( var attribute in attributeService.GetByCategoryId( category.Id ) ) { if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { attributeControl.AttributeList.Add( AttributeCache.Read( attribute ) ); } } } } } nfmMembers.ClearRows(); nfciContactInfo.ClearRows(); var groupMemberService = new GroupMemberService(rockContext); int defaultRoleId = _groupType.DefaultGroupRoleId ?? _groupType.Roles.Select( r => r.Id ).FirstOrDefault(); var location = new Location(); acAddress.GetValues( location ); foreach ( var groupMember in GroupMembers ) { string groupMemberGuidString = groupMember.Person.Guid.ToString().Replace( "-", "_" ); var groupMemberRow = new NewGroupMembersRow(); groupMemberRow.GroupTypeId = _groupType.Id; nfmMembers.Controls.Add( groupMemberRow ); groupMemberRow.ID = string.Format( "row_{0}", groupMemberGuidString ); groupMemberRow.RoleUpdated += groupMemberRow_RoleUpdated; groupMemberRow.DeleteClick += groupMemberRow_DeleteClick; groupMemberRow.PersonGuid = groupMember.Person.Guid; groupMemberRow.RequireGender = nfmMembers.RequireGender; groupMemberRow.RequireGrade = nfmMembers.RequireGrade; groupMemberRow.RoleId = groupMember.GroupRoleId; groupMemberRow.ShowGradeColumn = _isFamilyGroupType; groupMemberRow.ShowGradePicker = groupMember.GroupRoleId == _childRoleId; groupMemberRow.ValidationGroup = BlockValidationGroup; var contactInfoRow = new NewGroupContactInfoRow(); nfciContactInfo.Controls.Add( contactInfoRow ); contactInfoRow.ID = string.Format( "ci_row_{0}", groupMemberGuidString ); contactInfoRow.PersonGuid = groupMember.Person.Guid; contactInfoRow.IsMessagingEnabled = _SMSEnabled; contactInfoRow.PersonName = groupMember.Person.FullName; if ( _homePhone != null ) { var homePhoneNumber = groupMember.Person.PhoneNumbers.Where( p => p.NumberTypeValueId == _homePhone.Id ).FirstOrDefault(); if ( homePhoneNumber != null ) { contactInfoRow.HomePhoneNumber = PhoneNumber.FormattedNumber( homePhoneNumber.CountryCode, homePhoneNumber.Number ); contactInfoRow.HomePhoneCountryCode = homePhoneNumber.CountryCode; } else { contactInfoRow.HomePhoneNumber = string.Empty; contactInfoRow.HomePhoneCountryCode = string.Empty; } } if ( _cellPhone != null ) { var cellPhoneNumber = groupMember.Person.PhoneNumbers.Where( p => p.NumberTypeValueId == _cellPhone.Id ).FirstOrDefault(); if ( cellPhoneNumber != null ) { contactInfoRow.CellPhoneNumber = PhoneNumber.FormattedNumber( cellPhoneNumber.CountryCode, cellPhoneNumber.Number ); contactInfoRow.CellPhoneCountryCode = cellPhoneNumber.CountryCode; } else { contactInfoRow.CellPhoneNumber = string.Empty; contactInfoRow.CellPhoneCountryCode = string.Empty; } } contactInfoRow.Email = groupMember.Person.Email; if ( setSelection ) { if ( groupMember.Person != null ) { groupMemberRow.TitleValueId = groupMember.Person.TitleValueId; groupMemberRow.FirstName = groupMember.Person.FirstName; groupMemberRow.LastName = groupMember.Person.LastName; groupMemberRow.SuffixValueId = groupMember.Person.SuffixValueId; groupMemberRow.Gender = groupMember.Person.Gender; groupMemberRow.BirthDate = groupMember.Person.BirthDate; groupMemberRow.ConnectionStatusValueId = groupMember.Person.ConnectionStatusValueId; groupMemberRow.GradeOffset = groupMember.Person.GradeOffset; } } foreach ( var attributeControl in attributeControls ) { var attributeRow = new NewGroupAttributesRow(); attributeControl.Controls.Add( attributeRow ); attributeRow.ID = string.Format( "{0}_{1}", attributeControl.ID, groupMemberGuidString ); attributeRow.AttributeList = attributeControl.AttributeList; attributeRow.PersonGuid = groupMember.Person.Guid; attributeRow.PersonName = groupMember.Person.FullName; if ( setSelection ) { attributeRow.SetEditValues( groupMember.Person ); } } if ( Duplicates.ContainsKey( groupMember.Person.Guid ) ) { var dupRow = new HtmlGenericControl( "div" ); dupRow.AddCssClass( "row" ); dupRow.ID = string.Format( "dupRow_{0}", groupMemberGuidString ); phDuplicates.Controls.Add( dupRow ); var newPersonCol = new HtmlGenericControl( "div" ); newPersonCol.AddCssClass( "col-md-6" ); newPersonCol.ID = string.Format( "newPersonCol_{0}", groupMemberGuidString ); dupRow.Controls.Add( newPersonCol ); newPersonCol.Controls.Add( PersonHtmlPanel( groupMemberGuidString, groupMember.Person, groupMember.GroupRole, location, rockContext ) ); LinkButton lbRemoveMember = new LinkButton(); lbRemoveMember.ID = string.Format( "lbRemoveMember_{0}", groupMemberGuidString ); lbRemoveMember.AddCssClass( "btn btn-danger btn-xs" ); lbRemoveMember.Text = "Remove"; lbRemoveMember.Click += lbRemoveMember_Click; newPersonCol.Controls.Add( lbRemoveMember ); var dupPersonCol = new HtmlGenericControl( "div" ); dupPersonCol.AddCssClass( "col-md-6" ); dupPersonCol.ID = string.Format( "dupPersonCol_{0}", groupMemberGuidString ); dupRow.Controls.Add( dupPersonCol ); var duplicateHeader = new HtmlGenericControl( "h4" ); duplicateHeader.InnerText = "Possible Duplicate Records"; dupPersonCol.Controls.Add( duplicateHeader ); foreach( var duplicate in Duplicates[groupMember.Person.Guid] ) { GroupTypeRole groupTypeRole = null; Location duplocation = null; var dupGroupMember = groupMemberService.Queryable() .Where( a => a.PersonId == duplicate.Id ) .Where( a => a.Group.GroupTypeId == _groupType.Id ) .Select( s => new { s.GroupRole, GroupLocation = s.Group.GroupLocations.Where( a => a.GroupLocationTypeValue.Guid.Equals( _locationType.Guid ) ).Select( a => a.Location ).FirstOrDefault() } ) .FirstOrDefault(); if ( dupGroupMember != null ) { groupTypeRole = dupGroupMember.GroupRole; duplocation = dupGroupMember.GroupLocation; } dupPersonCol.Controls.Add( PersonHtmlPanel( groupMemberGuidString, duplicate, groupTypeRole, duplocation, rockContext ) ); } } } ShowPage(); }
/// <summary> /// Deletes the family's addresses, phone numbers, photos, viewed records, and people. /// TODO: delete attendance codes for attendance data that's about to be deleted when /// we delete the person record. /// </summary> /// <param name="families">The families.</param> /// <param name="rockContext">The rock context.</param> private void DeleteExistingFamilyData( XElement families, RockContext rockContext ) { PersonService personService = new PersonService( rockContext ); PhoneNumberService phoneNumberService = new PhoneNumberService( rockContext ); PersonViewedService personViewedService = new PersonViewedService( rockContext ); PageViewService pageViewService = new PageViewService( rockContext ); BinaryFileService binaryFileService = new BinaryFileService( rockContext ); PersonAliasService personAliasService = new PersonAliasService( rockContext ); PersonDuplicateService personDuplicateService = new PersonDuplicateService( rockContext ); NoteService noteService = new NoteService( rockContext ); AuthService authService = new AuthService( rockContext ); CommunicationService communicationService = new CommunicationService( rockContext ); CommunicationRecipientService communicationRecipientService = new CommunicationRecipientService( rockContext ); FinancialBatchService financialBatchService = new FinancialBatchService( rockContext ); FinancialTransactionService financialTransactionService = new FinancialTransactionService( rockContext ); PersonPreviousNameService personPreviousNameService = new PersonPreviousNameService( rockContext ); ConnectionRequestService connectionRequestService = new ConnectionRequestService( rockContext ); ConnectionRequestActivityService connectionRequestActivityService = new ConnectionRequestActivityService( rockContext ); // delete the batch data List<int> imageIds = new List<int>(); foreach ( var batch in financialBatchService.Queryable().Where( b => b.Name.StartsWith( "SampleData" ) ) ) { imageIds.AddRange( batch.Transactions.SelectMany( t => t.Images ).Select( i => i.BinaryFileId ).ToList() ); financialTransactionService.DeleteRange( batch.Transactions ); financialBatchService.Delete( batch ); } // delete all transaction images foreach ( var image in binaryFileService.GetByIds( imageIds ) ) { binaryFileService.Delete( image ); } foreach ( var elemFamily in families.Elements( "family" ) ) { Guid guid = elemFamily.Attribute( "guid" ).Value.Trim().AsGuid(); GroupService groupService = new GroupService( rockContext ); Group family = groupService.Get( guid ); if ( family != null ) { var groupMemberService = new GroupMemberService( rockContext ); var members = groupMemberService.GetByGroupId( family.Id, true ); // delete the people records string errorMessage; List<int> photoIds = members.Select( m => m.Person ).Where( p => p.PhotoId != null ).Select( a => (int)a.PhotoId ).ToList(); foreach ( var person in members.Select( m => m.Person ) ) { person.GivingGroup = null; person.GivingGroupId = null; person.PhotoId = null; // delete phone numbers foreach ( var phone in phoneNumberService.GetByPersonId( person.Id ) ) { if ( phone != null ) { phoneNumberService.Delete( phone ); } } // delete communication recipient foreach ( var recipient in communicationRecipientService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id ) ) { communicationRecipientService.Delete( recipient ); } // delete communication foreach ( var communication in communicationService.Queryable().Where( c => c.SenderPersonAliasId == person.PrimaryAlias.Id ) ) { communicationService.Delete( communication ); } // delete person viewed records foreach ( var view in personViewedService.GetByTargetPersonId( person.Id ) ) { personViewedService.Delete( view ); } // delete page viewed records foreach ( var view in pageViewService.GetByPersonId( person.Id ) ) { pageViewService.Delete( view ); } // delete notes created by them or on their record. foreach ( var note in noteService.Queryable().Where ( n => n.CreatedByPersonAlias.PersonId == person.Id || (n.NoteType.EntityTypeId == _personEntityTypeId && n.EntityId == person.Id ) ) ) { noteService.Delete( note ); } // delete previous names on their records foreach ( var previousName in personPreviousNameService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id ) ) { personPreviousNameService.Delete( previousName ); } // delete any GroupMember records they have foreach ( var groupMember in groupMemberService.Queryable().Where( gm => gm.PersonId == person.Id ) ) { groupMemberService.Delete( groupMember ); } //// delete any Authorization data //foreach ( var auth in authService.Queryable().Where( a => a.PersonId == person.Id ) ) //{ // authService.Delete( auth ); //} // delete their aliases foreach ( var alias in personAliasService.Queryable().Where( a => a.PersonId == person.Id ) ) { foreach ( var duplicate in personDuplicateService.Queryable().Where( d => d.DuplicatePersonAliasId == alias.Id ) ) { personDuplicateService.Delete( duplicate ); } personAliasService.Delete( alias ); } // delete any connection requests tied to them foreach ( var request in connectionRequestService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id || r.ConnectorPersonAlias.PersonId == person.Id ) ) { connectionRequestActivityService.DeleteRange( request.ConnectionRequestActivities ); connectionRequestService.Delete( request ); } // Save these changes so the CanDelete passes the check... //rockContext.ChangeTracker.DetectChanges(); rockContext.SaveChanges( disablePrePostProcessing: true ); if ( personService.CanDelete( person, out errorMessage ) ) { personService.Delete( person ); //rockContext.ChangeTracker.DetectChanges(); //rockContext.SaveChanges( disablePrePostProcessing: true ); } else { throw new Exception( string.Format( "Trying to delete {0}, but: {1}", person.FullName, errorMessage ) ); } } //rockContext.ChangeTracker.DetectChanges(); rockContext.SaveChanges( disablePrePostProcessing: true ); // delete all member photos foreach ( var photo in binaryFileService.GetByIds( photoIds ) ) { binaryFileService.Delete( photo ); } DeleteGroupAndMemberData( family, rockContext ); } } }
/// <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 rockContext = (RockContext)serviceInstance.Context; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 1 ) { var campusGuidList = selectionValues[0].Split( ',' ).AsGuidList(); List<int> campusIds = new List<int>(); foreach ( var campusGuid in campusGuidList ) { var campus = CampusCache.Read( campusGuid ); if ( campus != null ) { campusIds.Add( campus.Id ); } } if ( !campusIds.Any() ) { return null; } GroupMemberService groupMemberService = new GroupMemberService( rockContext ); var groupTypeFamily = GroupTypeCache.GetFamilyGroupType(); int groupTypeFamilyId = groupTypeFamily != null ? groupTypeFamily.Id : 0; var groupMemberServiceQry = groupMemberService.Queryable() .Where( xx => xx.Group.GroupTypeId == groupTypeFamilyId ) .Where( xx => campusIds.Contains( xx.Group.CampusId ?? 0 ) ); var qry = new PersonService( rockContext ).Queryable() .Where( p => groupMemberServiceQry.Any( xx => xx.PersonId == p.Id ) ); Expression extractedFilterExpression = FilterExpressionExtractor.Extract<Rock.Model.Person>( qry, parameterExpression, "p" ); return extractedFilterExpression; } return null; }
public IQueryable<GuestFamily> GetGuestsForFamily( int groupId ) { Guid knownRelationshipGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS ); Guid knownRelationshipOwner = new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER ); Guid knownRelationshipCanCheckin = new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_CAN_CHECK_IN ); RockContext rockContext = new RockContext(); GroupMemberService groupMemberService = new GroupMemberService( rockContext ); PersonService personService = new PersonService( rockContext ); var familyMembers = groupMemberService.Queryable() .Where( f => f.GroupId == groupId ) .Select( f => f.PersonId ); var familyMembersKnownRelationshipGroups = new GroupMemberService( rockContext ).Queryable() .Where( g => g.Group.GroupType.Guid == knownRelationshipGuid && g.GroupRole.Guid == knownRelationshipOwner && familyMembers.Contains( g.PersonId ) ) .Select( m => m.GroupId ); rockContext.Database.Log = s => System.Diagnostics.Debug.WriteLine( s ); var guests = groupMemberService.Queryable() .Where( g => g.GroupRole.Guid == knownRelationshipCanCheckin && familyMembersKnownRelationshipGroups.Contains( g.GroupId ) ) .Select( g => g.PersonId ) .Distinct().ToList(); var guestFamilies = new List<GuestFamily>(); rockContext.Database.Log = null; foreach ( var guestPersonId in guests ) { var families = personService.GetFamilies( guestPersonId ); foreach ( var family in families ) { if ( !guestFamilies.Select( f => f.Id ).Contains( family.Id ) ) { GuestFamily guestFamily = new GuestFamily(); guestFamily.Id = family.Id; guestFamily.Guid = family.Guid; guestFamily.Name = family.Name; guestFamily.FamilyMembers = new List<GuestFamilyMember>(); foreach ( var familyMember in family.Members ) { GuestFamilyMember guestFamilyMember = new GuestFamilyMember(); guestFamilyMember.Id = familyMember.PersonId; guestFamilyMember.PersonAliasId = familyMember.Person.PrimaryAliasId.Value; guestFamilyMember.Guid = familyMember.Person.Guid; guestFamilyMember.FirstName = familyMember.Person.NickName; guestFamilyMember.LastName = familyMember.Person.LastName; guestFamilyMember.PhotoUrl = familyMember.Person.PhotoUrl; guestFamilyMember.CanCheckin = guests.Contains( familyMember.PersonId ); guestFamilyMember.Role = familyMember.GroupRole.Name; guestFamilyMember.Age = familyMember.Person.Age; guestFamilyMember.Gender = familyMember.Person.Gender; guestFamily.FamilyMembers.Add( guestFamilyMember ); } guestFamilies.Add( guestFamily ); } } } return guestFamilies.AsQueryable(); }
/// <summary> /// Handles the Click event of the btnConfirm 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 btnConfirm_Click( object sender, EventArgs e ) { if ( Page.IsValid ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); var ids = Individuals.Select( i => i.PersonId ).ToList(); #region Individual Details Updates int? newTitleId = ddlTitle.SelectedValueAsInt(); int? newSuffixId = ddlSuffix.SelectedValueAsInt(); int? newConnectionStatusId = ddlStatus.SelectedValueAsInt(); int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt(); int? newInactiveReasonId = ddlInactiveReason.SelectedValueAsInt(); string newInactiveReasonNote = tbInactiveReasonNote.Text; Gender newGender = ddlGender.SelectedValue.ConvertToEnum<Gender>(); int? newMaritalStatusId = ddlMaritalStatus.SelectedValueAsInt(); int? newGraduationYear = null; if ( ypGraduation.SelectedYear.HasValue ) { newGraduationYear = ypGraduation.SelectedYear.Value; } int? newCampusId = cpCampus.SelectedCampusId; bool? newEmailActive = null; if ( !string.IsNullOrWhiteSpace( ddlIsEmailActive.SelectedValue ) ) { newEmailActive = ddlIsEmailActive.SelectedValue == "Active"; } EmailPreference? newEmailPreference = ddlEmailPreference.SelectedValue.ConvertToEnumOrNull<EmailPreference>(); string newEmailNote = tbEmailNote.Text; int? newReviewReason = ddlReviewReason.SelectedValueAsInt(); string newSystemNote = tbSystemNote.Text; string newReviewReasonNote = tbReviewReasonNote.Text; int inactiveStatusId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ).Id; var allChanges = new Dictionary<int, List<string>>(); var people = personService.Queryable().Where( p => ids.Contains( p.Id ) ).ToList(); foreach ( var person in people ) { var changes = new List<string>(); allChanges.Add( person.Id, changes ); if ( SelectedFields.Contains( ddlTitle.ClientID ) ) { History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) ); person.TitleValueId = newTitleId; } if ( SelectedFields.Contains( ddlSuffix.ClientID ) ) { History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) ); person.SuffixValueId = newSuffixId; } if ( SelectedFields.Contains( ddlStatus.ClientID ) ) { History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) ); person.ConnectionStatusValueId = newConnectionStatusId; } if ( SelectedFields.Contains( ddlRecordStatus.ClientID ) ) { History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) ); person.RecordStatusValueId = newRecordStatusId; if ( newRecordStatusId.HasValue && newRecordStatusId.Value == inactiveStatusId ) { History.EvaluateChange( changes, "Inactive Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newInactiveReasonId ) ); person.RecordStatusReasonValueId = newInactiveReasonId; if ( !string.IsNullOrWhiteSpace( newInactiveReasonNote ) ) { History.EvaluateChange( changes, "Inactive Reason Note", person.InactiveReasonNote, newInactiveReasonNote ); person.InactiveReasonNote = newInactiveReasonNote; } } } if ( SelectedFields.Contains( ddlGender.ClientID ) ) { History.EvaluateChange( changes, "Gender", person.Gender, newGender ); person.Gender = newGender; } if ( SelectedFields.Contains( ddlMaritalStatus.ClientID ) ) { History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) ); person.MaritalStatusValueId = newMaritalStatusId; } if ( SelectedFields.Contains( ddlGradePicker.ClientID ) ) { History.EvaluateChange( changes, "Graduation Year", person.GraduationYear, newGraduationYear ); person.GraduationYear = newGraduationYear; } if ( SelectedFields.Contains( ddlIsEmailActive.ClientID ) ) { History.EvaluateChange( changes, "Email Is Active", person.IsEmailActive ?? true, newEmailActive.Value ); person.IsEmailActive = newEmailActive; } if ( SelectedFields.Contains( ddlEmailPreference.ClientID ) ) { History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference ); person.EmailPreference = newEmailPreference.Value; } if ( SelectedFields.Contains( tbEmailNote.ClientID ) ) { History.EvaluateChange( changes, "Email Note", person.EmailNote, newEmailNote ); person.EmailNote = newEmailNote; } if ( SelectedFields.Contains( tbSystemNote.ClientID ) ) { History.EvaluateChange( changes, "System Note", person.SystemNote, newSystemNote ); person.SystemNote = newSystemNote; } if ( SelectedFields.Contains( ddlReviewReason.ClientID ) ) { History.EvaluateChange( changes, "Review Reason", DefinedValueCache.GetName( person.ReviewReasonValueId ), DefinedValueCache.GetName( newReviewReason ) ); person.ReviewReasonValueId = newReviewReason; } if ( SelectedFields.Contains( tbReviewReasonNote.ClientID ) ) { History.EvaluateChange( changes, "Review Reason Note", person.ReviewReasonNote, newReviewReasonNote ); person.ReviewReasonNote = newReviewReasonNote; } } if ( SelectedFields.Contains( cpCampus.ClientID ) && cpCampus.SelectedCampusId.HasValue ) { int campusId = cpCampus.SelectedCampusId.Value; Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); var familyMembers = new GroupMemberService( rockContext ).Queryable() .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid ) .Select( m => new { m.PersonId, m.GroupId } ) .Distinct() .ToList(); var families = new GroupMemberService( rockContext ).Queryable() .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid ) .Select( m => m.Group ) .Distinct() .ToList(); foreach ( int personId in ids ) { var familyIds = familyMembers.Where( m => m.PersonId == personId ).Select( m => m.GroupId ).ToList(); if ( familyIds.Count == 1 ) { int familyId = familyIds.FirstOrDefault(); var family = families.Where( g => g.Id == familyId ).FirstOrDefault(); { if ( family != null ) { family.CampusId = campusId; } familyMembers.RemoveAll( m => m.GroupId == familyId ); } } } rockContext.SaveChanges(); } // Update following if ( SelectedFields.Contains( ddlFollow.ClientID ) ) { var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" ); if ( personAliasEntityType != null ) { int personAliasEntityTypeId = personAliasEntityType.Id; bool follow = true; if ( !string.IsNullOrWhiteSpace( ddlFollow.SelectedValue ) ) { follow = ddlFollow.SelectedValue == "Add"; } var personAliasService = new PersonAliasService( rockContext ); var followingService = new FollowingService( rockContext ); if ( follow ) { var paQry = personAliasService.Queryable(); var alreadyFollowingIds = followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && f.PersonAlias.Id == CurrentPersonAlias.Id ) .Join( paQry, f => f.EntityId, p => p.Id, ( f, p ) => new { PersonAlias = p } ) .Select( p => p.PersonAlias.PersonId ) .Distinct() .ToList(); foreach ( int id in ids.Where( id => !alreadyFollowingIds.Contains( id ) ) ) { var following = new Following { EntityTypeId = personAliasEntityTypeId, EntityId = ( people.FirstOrDefault( p => p.Id == id ).PrimaryAliasId ) ?? 0, PersonAliasId = CurrentPersonAlias.Id }; followingService.Add( following ); } } else { var paQry = personAliasService.Queryable() .Where( p => ids.Contains( p.PersonId ) ) .Select( p => p.Id ); foreach ( var following in followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && paQry.Contains( f.EntityId ) && f.PersonAlias.Id == CurrentPersonAlias.Id ) ) { followingService.Delete( following ); } } } } rockContext.SaveChanges(); #endregion #region Attributes var selectedCategories = new List<CategoryCache>(); foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues() ) { var category = CategoryCache.Read( categoryGuid.AsGuid(), rockContext ); if ( category != null ) { selectedCategories.Add( category ); } } var attributes = new List<AttributeCache>(); var attributeValues = new Dictionary<int, string>(); int categoryIndex = 0; foreach ( var category in selectedCategories.OrderBy( c => c.Name ) ) { PanelWidget pw = null; string controlId = "pwAttributes_" + category.Id.ToString(); if ( categoryIndex % 2 == 0 ) { pw = phAttributesCol1.FindControl( controlId ) as PanelWidget; } else { pw = phAttributesCol2.FindControl( controlId ) as PanelWidget; } categoryIndex++; if ( pw != null ) { var orderedAttributeList = new AttributeService( rockContext ).GetByCategoryId( category.Id ) .OrderBy( a => a.Order ).ThenBy( a => a.Name ); foreach ( var attribute in orderedAttributeList ) { if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { var attributeCache = AttributeCache.Read( attribute.Id ); Control attributeControl = pw.FindControl( string.Format( "attribute_field_{0}", attribute.Id ) ); if ( attributeControl != null && SelectedFields.Contains( attributeControl.ClientID ) ) { string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues ); attributes.Add( attributeCache ); attributeValues.Add( attributeCache.Id, newValue ); } } } } } if ( attributes.Any() ) { foreach ( var person in people ) { person.LoadAttributes(); foreach ( var attribute in attributes ) { string originalValue = person.GetAttributeValue( attribute.Key ); string newValue = attributeValues[attribute.Id]; if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { Rock.Attribute.Helper.SaveAttributeValue( person, attribute, newValue, rockContext ); string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } History.EvaluateChange( allChanges[person.Id], attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } // Create the history records foreach ( var changes in allChanges ) { if ( changes.Value.Any() ) { HistoryService.AddChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), changes.Key, changes.Value ); } } rockContext.SaveChanges(); #endregion #region Add Note if ( !string.IsNullOrWhiteSpace( tbNote.Text ) && CurrentPerson != null ) { string text = tbNote.Text; bool isAlert = cbIsAlert.Checked; bool isPrivate = cbIsPrivate.Checked; var noteTypeService = new NoteTypeService( rockContext ); var noteType = noteTypeService.Get( Rock.SystemGuid.NoteType.PERSON_TIMELINE.AsGuid() ); if ( noteType != null ) { var notes = new List<Note>(); var noteService = new NoteService( rockContext ); foreach ( int id in ids ) { var note = new Note(); note.IsSystem = false; note.EntityId = id; note.Caption = isPrivate ? "You - Personal Note" : string.Empty; note.Text = tbNote.Text; note.IsAlert = cbIsAlert.Checked; note.NoteType = noteType; notes.Add( note ); noteService.Add( note ); } rockContext.WrapTransaction( () => { rockContext.SaveChanges(); foreach ( var note in notes ) { note.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext ); if ( isPrivate ) { note.MakePrivate( Authorization.VIEW, CurrentPerson, rockContext ); } } } ); } } #endregion #region Group int? groupId = gpGroup.SelectedValue.AsIntegerOrNull(); if ( groupId.HasValue ) { var group = new GroupService( rockContext ).Get( groupId.Value ); if ( group != null ) { var groupMemberService = new GroupMemberService( rockContext ); var existingMembers = groupMemberService.Queryable( "Group" ) .Where( m => m.GroupId == group.Id && ids.Contains( m.PersonId ) ) .ToList(); string action = ddlGroupAction.SelectedValue; if ( action == "Remove" ) { groupMemberService.DeleteRange( existingMembers ); rockContext.SaveChanges(); } else { var roleId = ddlGroupRole.SelectedValueAsInt(); var status = ddlGroupMemberStatus.SelectedValueAsEnum<GroupMemberStatus>(); // Get the attribute values updated var gm = new GroupMember(); gm.Group = group; gm.GroupId = group.Id; gm.LoadAttributes( rockContext ); var selectedGroupAttributes = new List<AttributeCache>(); var selectedGroupAttributeValues = new Dictionary<string, string>(); foreach ( var attributeCache in gm.Attributes.Select( a => a.Value ) ) { Control attributeControl = phAttributes.FindControl( string.Format( "attribute_field_{0}", attributeCache.Id ) ); if ( attributeControl != null && ( action == "Add" || SelectedFields.Contains( attributeControl.ClientID ) ) ) { string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues ); selectedGroupAttributes.Add( attributeCache ); selectedGroupAttributeValues.Add( attributeCache.Key, newValue ); } } if ( action == "Add" ) { if ( roleId.HasValue ) { var newGroupMembers = new List<GroupMember>(); var existingIds = existingMembers.Select( m => m.PersonId ).Distinct().ToList(); foreach ( int id in ids.Where( id => !existingIds.Contains( id ) ) ) { var groupMember = new GroupMember(); groupMember.GroupId = group.Id; groupMember.GroupRoleId = roleId.Value; groupMember.GroupMemberStatus = status; groupMember.PersonId = id; groupMemberService.Add( groupMember ); newGroupMembers.Add( groupMember ); } rockContext.SaveChanges(); if ( selectedGroupAttributes.Any() ) { foreach ( var groupMember in newGroupMembers ) { foreach ( var attribute in selectedGroupAttributes ) { Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext ); } } } } } else // Update { if ( SelectedFields.Contains( ddlGroupRole.ClientID ) && roleId.HasValue ) { foreach ( var member in existingMembers.Where( m => m.GroupRoleId != roleId.Value ) ) { if ( !existingMembers.Where( m => m.PersonId == member.PersonId && m.GroupRoleId == roleId.Value ).Any() ) { member.GroupRoleId = roleId.Value; } } } if ( SelectedFields.Contains( ddlGroupMemberStatus.ClientID ) ) { foreach ( var member in existingMembers ) { member.GroupMemberStatus = status; } } rockContext.SaveChanges(); if ( selectedGroupAttributes.Any() ) { foreach ( var groupMember in existingMembers ) { foreach ( var attribute in selectedGroupAttributes ) { Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext ); } } } } } } } #endregion pnlEntry.Visible = false; pnlConfirm.Visible = false; nbResult.Text = string.Format( "{0} {1} succesfully updated.", ids.Count().ToString( "N0" ), ( ids.Count() > 1 ? "people were" : "person was" ) ); ; pnlResult.Visible = true; } }
/// <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 ) { string cacheKey = "Rock.FindRelationships.Roles"; ObjectCache cache = Rock.Web.Cache.RockMemoryCache.Default; List<int> roles = cache[cacheKey] as List<int>; if ( roles == null ) { roles = new List<int>(); foreach ( var role in new GroupTypeRoleService( rockContext ).Queryable() .Where( r => r.GroupType.Guid.Equals( new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS ) ) ) ) { role.LoadAttributes( rockContext ); if ( role.Attributes.ContainsKey( "CanCheckin" ) ) { bool canCheckIn = false; if ( bool.TryParse( role.GetAttributeValue( "CanCheckin" ), out canCheckIn ) && canCheckIn ) { roles.Add( role.Id ); } } } CacheItemPolicy cacheItemPolicy = new CacheItemPolicy(); cacheItemPolicy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds( 300 ); cache.Set( cacheKey, roles, cacheItemPolicy ); } var checkInState = GetCheckInState( entity, out errorMessages ); if ( checkInState != null ) { if ( !roles.Any() ) { return true; } var family = checkInState.CheckIn.Families.Where( f => f.Selected ).FirstOrDefault(); if ( family != null ) { var service = new GroupMemberService( rockContext ); var familyMemberIds = family.People.Select( p => p.Person.Id ).ToList(); // Get the Known Relationship group id's for each person in the family var relationshipGroups = service.Queryable() .Where( g => g.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER ) ) && familyMemberIds.Contains( g.PersonId ) ) .Select( g => g.GroupId ) .ToList(); // Get anyone in any of those groups that has a role with the canCheckIn attribute set foreach ( var person in service.Queryable() .Where( g => relationshipGroups.Contains( g.GroupId ) && roles.Contains( g.GroupRoleId ) ) .Select( g => g.Person ) .Distinct().ToList() ) { if ( !family.People.Any( p => p.Person.Id == person.Id ) ) { var relatedPerson = new CheckInPerson(); relatedPerson.Person = person.Clone( false ); relatedPerson.FamilyMember = false; family.People.Add( relatedPerson ); } } return true; } else { errorMessages.Add( "There is not a family that is selected" ); } return false; } return false; }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override Expression GetExpression( RockContext context, MemberExpression entityIdProperty, string selection ) { string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 2 ) { GroupMemberService groupMemberService = new GroupMemberService( context ); Guid groupTypeGuid = selectionValues[0].AsGuid(); var groupMemberServiceQry = groupMemberService.Queryable().Where( xx => xx.Group.GroupType.Guid == groupTypeGuid ); var groupRoleGuids = selectionValues[1].Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).Select( n => n.AsGuid() ).ToList(); if ( groupRoleGuids.Count() > 0 ) { groupMemberServiceQry = groupMemberServiceQry.Where( xx => groupRoleGuids.Contains( xx.GroupRole.Guid ) ); } var qry = new PersonService( context ).Queryable() .Select( p => groupMemberServiceQry.Any( xx => xx.PersonId == p.Id ) ); Expression selectExpression = SelectExpressionExtractor.Extract<Rock.Model.Person>( qry, entityIdProperty, "p" ); return selectExpression; } return null; }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression( Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection ) { var service = new GroupMemberService( context ); var query = service.Queryable() .Select( gm => gm.GroupMemberStatus.ToString() ); var exp = SelectExpressionExtractor.Extract( query, entityIdProperty, "gm" ); return exp; }
/// <summary> /// Binds the group members grid. /// </summary> protected void BindGroupMembersGrid() { if ( _group != null ) { pnlGroupMembers.Visible = true; lHeading.Text = string.Format( "{0} {1}", _group.GroupType.GroupTerm, _group.GroupType.GroupMemberTerm.Pluralize() ); if ( _group.GroupType.Roles.Any() ) { nbRoleWarning.Visible = false; rFilter.Visible = true; gGroupMembers.Visible = true; var rockContext = new RockContext(); GroupMemberService groupMemberService = new GroupMemberService( rockContext ); var qry = groupMemberService.Queryable( "Person,GroupRole", true ).AsNoTracking() .Where( m => m.GroupId == _group.Id ); // Filter by First Name string firstName = tbFirstName.Text; if ( !string.IsNullOrWhiteSpace( firstName ) ) { qry = qry.Where( m => m.Person.FirstName.StartsWith( firstName ) ); } // Filter by Last Name string lastName = tbLastName.Text; if ( !string.IsNullOrWhiteSpace( lastName ) ) { qry = qry.Where( m => m.Person.LastName.StartsWith( lastName ) ); } // Filter by role var validGroupTypeRoles = _group.GroupType.Roles.Select( r => r.Id ).ToList(); var roles = new List<int>(); foreach ( string role in cblRole.SelectedValues ) { if ( !string.IsNullOrWhiteSpace( role ) ) { int roleId = int.MinValue; if ( int.TryParse( role, out roleId ) && validGroupTypeRoles.Contains( roleId ) ) { roles.Add( roleId ); } } } if ( roles.Any() ) { qry = qry.Where( m => roles.Contains( m.GroupRoleId ) ); } // Filter by Status var statuses = new List<GroupMemberStatus>(); foreach ( string status in cblStatus.SelectedValues ) { if ( !string.IsNullOrWhiteSpace( status ) ) { statuses.Add( status.ConvertToEnum<GroupMemberStatus>() ); } } if ( statuses.Any() ) { qry = qry.Where( m => statuses.Contains( m.GroupMemberStatus ) ); } // Filter query by any configured attribute filters if ( AvailableAttributes != null && AvailableAttributes.Any() ) { var attributeValueService = new AttributeValueService( rockContext ); var parameterExpression = attributeValueService.ParameterExpression; foreach ( var attribute in AvailableAttributes ) { var filterControl = phAttributeFilters.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 ); qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) ); } } } } _inactiveStatus = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ); SortProperty sortProperty = gGroupMembers.SortProperty; bool hasGroupRequirements = new GroupRequirementService( rockContext ).Queryable().Where( a => a.GroupId == _group.Id ).Any(); // If there are group requirements that that member doesn't meet, show an icon in the grid bool includeWarnings = false; var groupMemberIdsThatLackGroupRequirements = new GroupService( rockContext ).GroupMembersNotMeetingRequirements( _group.Id, includeWarnings ).Select( a => a.Key.Id ); List<GroupMember> groupMembersList = null; if ( sortProperty != null ) { groupMembersList = qry.Sort( sortProperty ).ToList(); } else { groupMembersList = qry.OrderBy( a => a.GroupRole.Order ).ThenBy( a => a.Person.LastName ).ThenBy( a => a.Person.FirstName ).ToList(); } // Since we're not binding to actual group member list, but are using AttributeField columns, // we need to save the workflows into the grid's object list gGroupMembers.ObjectList = new Dictionary<string, object>(); groupMembersList.ForEach( m => gGroupMembers.ObjectList.Add( m.Id.ToString(), m ) ); gGroupMembers.EntityTypeId = EntityTypeCache.Read( Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid() ).Id; gGroupMembers.DataSource = groupMembersList.Select( m => new { m.Id, m.Guid, m.PersonId, Name = m.Person.NickName + " " + m.Person.LastName + ( hasGroupRequirements && groupMemberIdsThatLackGroupRequirements.Contains( m.Id ) ? " <i class='fa fa-exclamation-triangle text-warning'></i>" : string.Empty ) + ( !string.IsNullOrEmpty( m.Note ) ? " <i class='fa fa-file-text-o text-info'></i>" : string.Empty ), GroupRole = m.GroupRole.Name, m.GroupMemberStatus, RecordStatusValueId = m.Person.RecordStatusValueId, IsDeceased = m.Person.IsDeceased } ).ToList(); gGroupMembers.DataBind(); } else { nbRoleWarning.Text = string.Format( "{0} cannot be added to this {1} because the '{2}' group type does not have any roles defined.", _group.GroupType.GroupMemberTerm.Pluralize(), _group.GroupType.GroupTerm, _group.GroupType.Name ); nbRoleWarning.Visible = true; rFilter.Visible = false; gGroupMembers.Visible = false; } } else { pnlGroupMembers.Visible = false; } }
/// <summary> /// Handles the Delete event of the gContactList control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param> protected void gContactList_Delete( object sender, Rock.Web.UI.Controls.RowEventArgs e ) { int? businessId = hfBusinessId.Value.AsIntegerOrNull(); if ( businessId.HasValue ) { var businessContactId = e.RowKeyId; var rockContext = new RockContext(); var groupMemberService = new GroupMemberService( rockContext ); Guid businessContact = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT.AsGuid(); Guid business = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS.AsGuid(); Guid ownerGuid = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid(); foreach ( var groupMember in groupMemberService.Queryable() .Where( m => ( // The contact person in the business's known relationships m.PersonId == businessContactId && m.GroupRole.Guid.Equals( businessContact ) && m.Group.Members.Any( o => o.PersonId == businessId && o.GroupRole.Guid.Equals( ownerGuid ) ) ) || ( // The business in the person's know relationships m.PersonId == businessId && m.GroupRole.Guid.Equals( business ) && m.Group.Members.Any( o => o.PersonId == businessContactId && o.GroupRole.Guid.Equals( ownerGuid ) ) ) ) ) { groupMemberService.Delete( groupMember ); } rockContext.SaveChanges(); BindContactListGrid( new PersonService( rockContext ).Get( businessId.Value ) ); } }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event. /// </summary> /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnLoad( EventArgs e ) { base.OnLoad( e ); if ( !Page.IsPostBack ) { RockContext rockContext = new RockContext(); Group group = null; Guid personGuid = Guid.Empty; // get group from url if ( Request["GroupId"] != null || Request["GroupGuid"] != null ) { if ( Request["GroupId"] != null ) { int groupId = 0; if ( Int32.TryParse( Request["GroupId"], out groupId ) ) { group = new GroupService( rockContext ).Queryable().Where( g => g.Id == groupId ).FirstOrDefault(); } } else { Guid groupGuid = Request["GroupGuid"].AsGuid(); group = new GroupService( rockContext ).Queryable().Where( g => g.Guid == groupGuid ).FirstOrDefault(); } } else { Guid groupGuid = Guid.Empty; if ( Guid.TryParse( GetAttributeValue( "DefaultGroup" ), out groupGuid ) ) { group = new GroupService( rockContext ).Queryable().Where( g => g.Guid == groupGuid ).FirstOrDefault(); ; } } if ( group == null ) { lAlerts.Text = "Could not determine the group to add to."; return; } // get person Person person = null; if ( !string.IsNullOrWhiteSpace(Request["PersonGuid"]) ) { person = new PersonService( rockContext ).Get( Request["PersonGuid"].AsGuid() ); } if ( person == null ) { lAlerts.Text += "A person could not be found for the identifier provided."; return; } // hide alert divAlert.Visible = false; // get status var groupMemberStatus = this.GetAttributeValue( "GroupMemberStatus" ).ConvertToEnum<GroupMemberStatus>( GroupMemberStatus.Active ); // load merge fields var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Group", group ); mergeFields.Add( "Person", person ); mergeFields.Add( "CurrentPerson", CurrentPerson ); // show debug info? bool enableDebug = GetAttributeValue( "EnableDebug" ).AsBoolean(); if ( enableDebug && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } var groupMemberService = new GroupMemberService(rockContext); var groupMemberList = groupMemberService.Queryable() .Where( m => m.GroupId == group.Id && m.PersonId == person.Id ) .ToList(); if (groupMemberList.Count > 0 ) { foreach(var groupMember in groupMemberList ) { if ( GetAttributeValue( "Inactivate" ).AsBoolean() ) { groupMember.GroupMemberStatus = GroupMemberStatus.Inactive; } else { groupMemberService.Delete( groupMember ); } rockContext.SaveChanges(); } lContent.Text = GetAttributeValue( "SuccessMessage" ).ResolveMergeFields( mergeFields ); } else { if ( GetAttributeValue( "WarnWhenNotInGroup").AsBoolean() ) { lContent.Text = GetAttributeValue( "NotInGroupMessage" ).ResolveMergeFields( mergeFields ); } else { lContent.Text = GetAttributeValue( "SuccessMessage" ).ResolveMergeFields( mergeFields ); } } } }
/// <summary> /// Handles the SaveClick event of the mdAddContact control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void mdAddContact_SaveClick( object sender, EventArgs e ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); var groupService = new GroupService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var business = personService.Get( int.Parse( hfBusinessId.Value ) ); int? contactId = ppContact.PersonId; if ( contactId.HasValue && contactId.Value > 0 ) { // Get the relationship roles to use var knownRelationshipGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid() ); int businessContactRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); int businessRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); int ownerRoleId = knownRelationshipGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); if ( ownerRoleId > 0 && businessContactRoleId > 0 && businessRoleId > 0 ) { // get the known relationship group of the business contact // add the business as a group member of that group using the group role of GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS var contactKnownRelationshipGroup = groupMemberService.Queryable() .Where( g => g.GroupRoleId == ownerRoleId && g.PersonId == contactId.Value ) .Select( g => g.Group ) .FirstOrDefault(); if (contactKnownRelationshipGroup == null) { // In some cases person may not yet have a know relationship group type contactKnownRelationshipGroup = new Group(); groupService.Add( contactKnownRelationshipGroup ); contactKnownRelationshipGroup.Name = "Known Relationship"; contactKnownRelationshipGroup.GroupTypeId = knownRelationshipGroupType.Id; var ownerMember = new GroupMember(); ownerMember.PersonId = contactId.Value; ownerMember.GroupRoleId = ownerRoleId; contactKnownRelationshipGroup.Members.Add( ownerMember ); } var groupMember = new GroupMember(); groupMember.PersonId = int.Parse( hfBusinessId.Value ); groupMember.GroupRoleId = businessRoleId; contactKnownRelationshipGroup.Members.Add( groupMember ); // get the known relationship group of the business // add the business contact as a group member of that group using the group role of GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT var businessKnownRelationshipGroup = groupMemberService.Queryable() .Where( g => g.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER ) ) && g.PersonId == business.Id ) .Select( g => g.Group ).FirstOrDefault(); var businessGroupMember = new GroupMember(); businessGroupMember.PersonId = contactId.Value; businessGroupMember.GroupRoleId = businessContactRoleId; businessKnownRelationshipGroup.Members.Add( businessGroupMember ); rockContext.SaveChanges(); } } mdAddContact.Hide(); hfModalOpen.Value = string.Empty; BindContactListGrid( business ); }
/// <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> /// Updates the group member. /// </summary> /// <param name="businessId">The business identifier.</param> /// <param name="groupType">Type of the group.</param> /// <param name="groupName">Name of the group.</param> /// <param name="campusId">The campus identifier.</param> /// <param name="groupRoleId">The group role identifier.</param> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private GroupMember UpdateGroupMember( int businessId, GroupTypeCache groupType, string groupName, int? campusId, int groupRoleId, RockContext rockContext ) { var groupMemberService = new GroupMemberService( rockContext ); GroupMember groupMember = groupMemberService.Queryable( "Group" ) .Where( m => m.PersonId == businessId && m.GroupRoleId == groupRoleId ) .FirstOrDefault(); if ( groupMember == null ) { groupMember = new GroupMember(); groupMember.Group = new Group(); groupMemberService.Add( groupMember ); } groupMember.PersonId = businessId; groupMember.GroupRoleId = groupRoleId; groupMember.GroupMemberStatus = GroupMemberStatus.Active; groupMember.Group.GroupTypeId = groupType.Id; groupMember.Group.Name = groupName; groupMember.Group.CampusId = campusId; return groupMember; }