/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(dbContext as RockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId.HasValue && a.GroupId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } // manually set any attendance search group ids to null var attendanceService = new AttendanceService(dbContext as RockContext); foreach (var attendance in attendanceService.Queryable() .Where(a => a.SearchResultGroupId.HasValue && a.SearchResultGroupId.Value == this.Id)) { attendance.SearchResultGroupId = null; } } base.PreSaveChanges(dbContext, state); }
/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(dbContext as RockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } } }
/// <summary> /// Called before the save operation is executed. /// </summary> protected override void PreSave() { var rockContext = ( RockContext )this.RockContext; if (State == EntityContextState.Deleted) { Entity.ChildGroupTypes.Clear(); // manually delete any grouprequirements of this grouptype since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(rockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupTypeId.HasValue && a.GroupTypeId == Entity.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } } // clean up the index if (State == EntityContextState.Deleted && Entity.IsIndexEnabled) { Entity.DeleteIndexedDocumentsByGroupType(Entity.Id); } else if (State == EntityContextState.Modified) { // check if indexing is enabled var changeEntry = rockContext.ChangeTracker.Entries <GroupType>().Where(a => a.Entity == Entity).FirstOrDefault(); if (changeEntry != null) { var originalIndexState = ( bool )changeEntry.OriginalValues[nameof(GroupType.IsIndexEnabled)]; if (originalIndexState == true && Entity.IsIndexEnabled == false) { // clear out index items Entity.DeleteIndexedDocumentsByGroupType(Entity.Id); } else if (Entity.IsIndexEnabled == true) { // if indexing is enabled then bulk index - needed as an attribute could have changed from IsIndexed Entity.BulkIndexDocumentsByGroupType(Entity.Id); } } } base.PreSave(); }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { ChildGroupTypes.Clear(); // manually delete any grouprequirements of this grouptype since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(dbContext as RockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupTypeId.HasValue && a.GroupTypeId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } } // clean up the index if (state == System.Data.Entity.EntityState.Deleted && IsIndexEnabled) { this.DeleteIndexedDocumentsByGroupType(this.Id); } else if (state == System.Data.Entity.EntityState.Modified) { // check if indexing is enabled var changeEntry = dbContext.ChangeTracker.Entries <GroupType>().Where(a => a.Entity == this).FirstOrDefault(); if (changeEntry != null) { var originalIndexState = (bool)changeEntry.OriginalValues["IsIndexEnabled"]; if (originalIndexState == true && IsIndexEnabled == false) { // clear out index items this.DeleteIndexedDocumentsByGroupType(Id); } else if (IsIndexEnabled == true) { // if indexing is enabled then bulk index - needed as an attribute could have changed from IsIndexed BulkIndexDocumentsByGroupType(Id); } } } base.PreSaveChanges(dbContext, state); }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Data.DbContext dbContext, DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChangeList = new History.HistoryChangeList(); switch (entry.State) { case System.Data.Entity.EntityState.Added: { HistoryChangeList.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Group").SetNewValue(Name); History.EvaluateChange(HistoryChangeList, "Name", string.Empty, Name); History.EvaluateChange(HistoryChangeList, "Description", string.Empty, Description); History.EvaluateChange(HistoryChangeList, "Group Type", (int?)null, GroupType, GroupTypeId); History.EvaluateChange(HistoryChangeList, "Campus", (int?)null, Campus, CampusId); History.EvaluateChange(HistoryChangeList, "Security Role", (bool?)null, IsSecurityRole); History.EvaluateChange(HistoryChangeList, "Active", (bool?)null, IsActive); History.EvaluateChange(HistoryChangeList, "Allow Guests", (bool?)null, AllowGuests); History.EvaluateChange(HistoryChangeList, "Public", (bool?)null, IsPublic); History.EvaluateChange(HistoryChangeList, "Group Capacity", (int?)null, GroupCapacity); // if this is a new record, but is saved with IsActive=False, set the InactiveDateTime if it isn't set already if (!this.IsActive) { this.InactiveDateTime = this.InactiveDateTime ?? RockDateTime.Now; } break; } case System.Data.Entity.EntityState.Modified: { var originalIsActive = entry.OriginalValues["IsActive"].ToStringSafe().AsBoolean(); History.EvaluateChange(HistoryChangeList, "Name", entry.OriginalValues["Name"].ToStringSafe(), Name); History.EvaluateChange(HistoryChangeList, "Description", entry.OriginalValues["Description"].ToStringSafe(), Description); History.EvaluateChange(HistoryChangeList, "Group Type", entry.OriginalValues["GroupTypeId"].ToStringSafe().AsIntegerOrNull(), GroupType, GroupTypeId); History.EvaluateChange(HistoryChangeList, "Campus", entry.OriginalValues["CampusId"].ToStringSafe().AsIntegerOrNull(), Campus, CampusId); History.EvaluateChange(HistoryChangeList, "Security Role", entry.OriginalValues["IsSecurityRole"].ToStringSafe().AsBoolean(), IsSecurityRole); History.EvaluateChange(HistoryChangeList, "Active", originalIsActive, IsActive); History.EvaluateChange(HistoryChangeList, "Allow Guests", entry.OriginalValues["AllowGuests"].ToStringSafe().AsBooleanOrNull(), AllowGuests); History.EvaluateChange(HistoryChangeList, "Public", entry.OriginalValues["IsPublic"].ToStringSafe().AsBoolean(), IsPublic); History.EvaluateChange(HistoryChangeList, "Group Capacity", entry.OriginalValues["GroupCapacity"].ToStringSafe().AsIntegerOrNull(), GroupCapacity); History.EvaluateChange(HistoryChangeList, "Archived", entry.OriginalValues["IsArchived"].ToStringSafe().AsBoolean(), this.IsArchived); // IsActive was modified, set the InactiveDateTime if it changed to Inactive, or set it to NULL if it changed to Active if (originalIsActive != this.IsActive) { if (!this.IsActive) { // if the caller didn't already set InactiveDateTime, set it to now this.InactiveDateTime = this.InactiveDateTime ?? RockDateTime.Now; } else { this.InactiveDateTime = null; } } break; } case System.Data.Entity.EntityState.Deleted: { HistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, null); // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(rockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId.HasValue && a.GroupId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } // manually set any attendance search group ids to null var attendanceService = new AttendanceService(rockContext); var attendancesToNullSearchResultGroupId = attendanceService.Queryable() .Where(a => a.SearchResultGroupId.HasValue && a.SearchResultGroupId.Value == this.Id); dbContext.BulkUpdate(attendancesToNullSearchResultGroupId, a => new Attendance { SearchResultGroupId = null }); // since we can't put a CascadeDelete on both Attendance.Occurrence.GroupId and Attendance.OccurrenceId, manually delete all Attendance records associated with this GroupId var attendancesToDelete = attendanceService.Queryable() .Where(a => a.Occurrence.GroupId.HasValue && a.Occurrence.GroupId.Value == this.Id); if (attendancesToDelete.Any()) { dbContext.BulkDelete(attendancesToDelete); } break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Data.DbContext dbContext, DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChanges = new List <string>(); switch (entry.State) { case System.Data.Entity.EntityState.Added: { HistoryChanges.Add("Group Created"); History.EvaluateChange(HistoryChanges, "Name", string.Empty, Name); History.EvaluateChange(HistoryChanges, "Description", string.Empty, Description); History.EvaluateChange(HistoryChanges, "Group Type", (int?)null, GroupType, GroupTypeId); History.EvaluateChange(HistoryChanges, "Campus", (int?)null, Campus, CampusId); History.EvaluateChange(HistoryChanges, "Security Role", (bool?)null, IsSecurityRole); History.EvaluateChange(HistoryChanges, "Active", (bool?)null, IsActive); History.EvaluateChange(HistoryChanges, "Allow Guests", (bool?)null, AllowGuests); History.EvaluateChange(HistoryChanges, "Public", (bool?)null, IsPublic); History.EvaluateChange(HistoryChanges, "Group Capacity", (int?)null, GroupCapacity); break; } case System.Data.Entity.EntityState.Modified: { History.EvaluateChange(HistoryChanges, "Name", entry.OriginalValues["Name"].ToStringSafe(), Name); History.EvaluateChange(HistoryChanges, "Description", entry.OriginalValues["Description"].ToStringSafe(), Description); History.EvaluateChange(HistoryChanges, "Group Type", entry.OriginalValues["GroupTypeId"].ToStringSafe().AsIntegerOrNull(), GroupType, GroupTypeId); History.EvaluateChange(HistoryChanges, "Campus", entry.OriginalValues["CampusId"].ToStringSafe().AsIntegerOrNull(), Campus, CampusId); History.EvaluateChange(HistoryChanges, "Security Role", entry.OriginalValues["IsSecurityRole"].ToStringSafe().AsBoolean(), IsSecurityRole); History.EvaluateChange(HistoryChanges, "Active", entry.OriginalValues["IsActive"].ToStringSafe().AsBoolean(), IsActive); History.EvaluateChange(HistoryChanges, "Allow Guests", entry.OriginalValues["AllowGuests"].ToStringSafe().AsBooleanOrNull(), AllowGuests); History.EvaluateChange(HistoryChanges, "Public", entry.OriginalValues["IsPublic"].ToStringSafe().AsBoolean(), IsPublic); History.EvaluateChange(HistoryChanges, "Group Capacity", entry.OriginalValues["GroupCapacity"].ToStringSafe().AsIntegerOrNull(), GroupCapacity); break; } case System.Data.Entity.EntityState.Deleted: { HistoryChanges.Add("Deleted"); // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(rockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId.HasValue && a.GroupId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } // manually set any attendance search group ids to null var attendanceService = new AttendanceService(rockContext); foreach (var attendance in attendanceService.Queryable() .Where(a => a.SearchResultGroupId.HasValue && a.SearchResultGroupId.Value == this.Id)) { attendance.SearchResultGroupId = null; } break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Called before the save operation is executed. /// </summary> protected override void PreSave() { HistoryChangeList = new History.HistoryChangeList(); var rockContext = ( RockContext )this.RockContext; _FamilyCampusIsChanged = false; switch (State) { case EntityContextState.Added: { HistoryChangeList.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Group").SetNewValue(Entity.Name); History.EvaluateChange(HistoryChangeList, "Name", string.Empty, Entity.Name); History.EvaluateChange(HistoryChangeList, "Description", string.Empty, Entity.Description); History.EvaluateChange(HistoryChangeList, "Group Type", ( int? )null, Entity.GroupType, Entity.GroupTypeId); History.EvaluateChange(HistoryChangeList, "Campus", ( int? )null, Entity.Campus, Entity.CampusId); History.EvaluateChange(HistoryChangeList, "Security Role", ( bool? )null, Entity.IsSecurityRole); History.EvaluateChange(HistoryChangeList, "Active", ( bool? )null, Entity.IsActive); History.EvaluateChange(HistoryChangeList, "Allow Guests", ( bool? )null, Entity.AllowGuests); History.EvaluateChange(HistoryChangeList, "Public", ( bool? )null, Entity.IsPublic); History.EvaluateChange(HistoryChangeList, "Group Capacity", ( int? )null, Entity.GroupCapacity); // if this is a new record, but is saved with IsActive=False, set the InactiveDateTime if it isn't set already if (!Entity.IsActive) { Entity.InactiveDateTime = Entity.InactiveDateTime ?? RockDateTime.Now; } break; } case EntityContextState.Modified: { var originalIsActive = OriginalValues[nameof(Group.IsActive)].ToStringSafe().AsBoolean(); DateTime?originalInactiveDateTime = OriginalValues["InactiveDateTime"].ToStringSafe().AsDateTime(); var originalIsArchived = OriginalValues[nameof(Group.IsArchived)].ToStringSafe().AsBoolean(); DateTime?originalArchivedDateTime = OriginalValues[nameof(Group.ArchivedDateTime)].ToStringSafe().AsDateTime(); History.EvaluateChange(HistoryChangeList, "Name", OriginalValues[nameof(Group.Name)].ToStringSafe(), Entity.Name); History.EvaluateChange(HistoryChangeList, "Description", OriginalValues[nameof(Group.Description)].ToStringSafe(), Entity.Description); History.EvaluateChange(HistoryChangeList, "Group Type", OriginalValues[nameof(Group.GroupTypeId)].ToStringSafe().AsIntegerOrNull(), Entity.GroupType, Entity.GroupTypeId); History.EvaluateChange(HistoryChangeList, "Campus", OriginalValues[nameof(Group.CampusId)].ToStringSafe().AsIntegerOrNull(), Entity.Campus, Entity.CampusId); History.EvaluateChange(HistoryChangeList, "Security Role", OriginalValues[nameof(Group.IsSecurityRole)].ToStringSafe().AsBoolean(), Entity.IsSecurityRole); History.EvaluateChange(HistoryChangeList, "Active", originalIsActive, Entity.IsActive); History.EvaluateChange(HistoryChangeList, "Allow Guests", OriginalValues[nameof(Group.AllowGuests)].ToStringSafe().AsBooleanOrNull(), Entity.AllowGuests); History.EvaluateChange(HistoryChangeList, "Public", OriginalValues[nameof(Group.IsPublic)].ToStringSafe().AsBoolean(), Entity.IsPublic); History.EvaluateChange(HistoryChangeList, "Group Capacity", OriginalValues[nameof(Group.GroupCapacity)].ToStringSafe().AsIntegerOrNull(), Entity.GroupCapacity); History.EvaluateChange(HistoryChangeList, "Archived", OriginalValues[nameof(Group.IsArchived)].ToStringSafe().AsBoolean(), Entity.IsArchived); // IsActive was modified, set the InactiveDateTime if it changed to Inactive, or set it to NULL if it changed to Active if (originalIsActive != Entity.IsActive) { if (!Entity.IsActive) { // if the caller didn't already set InactiveDateTime, set it to now Entity.InactiveDateTime = Entity.InactiveDateTime ?? RockDateTime.Now; } else { Entity.InactiveDateTime = null; } DateTime?newInactiveDateTime = Entity.InactiveDateTime; UpdateGroupMembersActiveStatusFromGroupStatus(rockContext, originalIsActive, originalInactiveDateTime, Entity.IsActive, newInactiveDateTime); } // IsArchived was modified, set the ArchivedDateTime if it changed to IsArchived, or set it to NULL if IsArchived was changed to false if (originalIsArchived != Entity.IsArchived) { if (Entity.IsArchived) { // if the caller didn't already set ArchivedDateTime, set it to now Entity.ArchivedDateTime = Entity.ArchivedDateTime ?? RockDateTime.Now; } else { Entity.ArchivedDateTime = null; } DateTime?newArchivedDateTime = Entity.ArchivedDateTime; UpdateGroupMembersArchivedValueFromGroupArchivedValue(rockContext, originalIsArchived, originalArchivedDateTime, Entity.IsArchived, newArchivedDateTime); } // If Campus is modified for an existing Family Group, set a flag to trigger updates for calculated field Person.PrimaryCampusId. var group = Entity as Group; var familyGroupTypeId = GroupTypeCache.GetFamilyGroupType().Id; _FamilyCampusIsChanged = (group.GroupTypeId == familyGroupTypeId && group.CampusId.GetValueOrDefault(0) != OriginalValues["CampusId"].ToStringSafe().AsInteger()); break; } case EntityContextState.Deleted: { HistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, null); // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(rockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId.HasValue && a.GroupId == Entity.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } // manually set any attendance search group ids to null var attendanceService = new AttendanceService(rockContext); var attendancesToNullSearchResultGroupId = attendanceService.Queryable() .Where(a => a.SearchResultGroupId.HasValue && a.SearchResultGroupId.Value == Entity.Id); rockContext.BulkUpdate(attendancesToNullSearchResultGroupId, a => new Attendance { SearchResultGroupId = null }); // since we can't put a CascadeDelete on both Attendance.Occurrence.GroupId and Attendance.OccurrenceId, manually delete all Attendance records associated with this GroupId var attendancesToDelete = attendanceService.Queryable() .Where(a => a.Occurrence.GroupId.HasValue && a.Occurrence.GroupId.Value == Entity.Id); if (attendancesToDelete.Any()) { rockContext.BulkDelete(attendancesToDelete); } break; } } base.PreSave(); }
/// <summary> /// Called after the save operation has been executed /// </summary> /// <remarks> /// This method is only called if <see cref="M:Rock.Data.EntitySaveHook`1.PreSave" /> returns /// without error. /// </remarks> protected override void PostSave() { // Get the current person's alias ID from the current context. var currentPersonAliasId = DbContext.GetCurrentPersonAlias()?.Id; var connectionRequest = this.Entity as ConnectionRequest; // Create and send the change notification message now that the connection request has been saved. var processConnectionRequestChangeMessage = GetProcessConnectionRequestChangeMessage(Entry, connectionRequest, currentPersonAliasId); processConnectionRequestChangeMessage.SendWhen(this.DbContext.WrappedTransactionCompletedTask); var rockContext = ( RockContext )this.RockContext; if (Entity.ConnectionStatus == null) { Entity.ConnectionStatus = new ConnectionStatusService(rockContext).Get(Entity.ConnectionStatusId); } if (Entity.ConnectionStatus != null && Entity.ConnectionStatus.AutoInactivateState && Entity.ConnectionState != ConnectionState.Inactive) { Entity.ConnectionState = ConnectionState.Inactive; rockContext.SaveChanges(); } var connectionStatusAutomationsQuery = new ConnectionStatusAutomationService(rockContext).Queryable().Where(a => a.SourceStatusId == Entity.ConnectionStatusId); if (this.Entity._runAutomationsInPostSaveChanges && connectionStatusAutomationsQuery.Any()) { var connectionStatusAutomationsList = connectionStatusAutomationsQuery.AsNoTracking().OrderBy(a => a.AutomationName).ToList(); var connectionStatusAutomations = connectionStatusAutomationsList; int changedStatusCount = 0; foreach (var connectionStatusAutomation in connectionStatusAutomations) { if (this.Entity.processedConnectionStatusAutomations.Contains(connectionStatusAutomation.Id)) { // to avoid recursion, skip over automations that have already been processed in this thread. continue; } if (Entity.ConnectionStatusId == connectionStatusAutomation.DestinationStatusId) { // If already have this status, no need to figure out if it needs to be set to this status, // or to set the status. this.Entity.processedConnectionStatusAutomations.Add(connectionStatusAutomation.Id); continue; } bool isAutomationValid = true; if (connectionStatusAutomation.DataViewId.HasValue) { // Get the dataview configured for the connection request var dataViewService = new DataViewService(rockContext); var dataview = dataViewService.Get(connectionStatusAutomation.DataViewId.Value); if (dataview != null) { var dataViewQuery = new ConnectionRequestService(rockContext).GetQueryUsingDataView(dataview); isAutomationValid = dataViewQuery.Any(a => a.Id == Entity.Id); } } if (isAutomationValid && connectionStatusAutomation.GroupRequirementsFilter != GroupRequirementsFilter.Ignore) { // Group Requirement can't be meet when either placement group or placement group role id is missing if (!Entity.AssignedGroupId.HasValue || !Entity.AssignedGroupMemberRoleId.HasValue) { isAutomationValid = false; } else { var isRequirementMeet = true; var group = new GroupService(rockContext).Get(Entity.AssignedGroupId.Value); var hasGroupRequirement = new GroupRequirementService(rockContext).Queryable().Where(a => (a.GroupId.HasValue && a.GroupId == group.Id) || (a.GroupTypeId.HasValue && a.GroupTypeId == group.GroupTypeId)).Any(); if (hasGroupRequirement) { var requirementsResults = group.PersonMeetsGroupRequirements( rockContext, Entity.PersonAlias.PersonId, Entity.AssignedGroupMemberRoleId.Value); if (requirementsResults != null && requirementsResults .Where(a => a.MeetsGroupRequirement != MeetsGroupRequirement.NotApplicable) .Any(r => r.MeetsGroupRequirement != MeetsGroupRequirement.Meets && r.MeetsGroupRequirement != MeetsGroupRequirement.MeetsWithWarning) ) { isRequirementMeet = false; } } // connection request based on if group requirement is meet or not is added to list for status update isAutomationValid = (connectionStatusAutomation.GroupRequirementsFilter == GroupRequirementsFilter.DoesNotMeet && !isRequirementMeet) || (connectionStatusAutomation.GroupRequirementsFilter == GroupRequirementsFilter.MustMeet && isRequirementMeet); } } if (isAutomationValid) { if (Entity.SetConnectionStatusFromAutomationLoop(connectionStatusAutomation)) { changedStatusCount++; rockContext.SaveChanges(); } } } } var hasHistoryChanges = HistoryChangeList?.Any() == true; var hasPersonHistoryChanges = PersonHistoryChangeList?.Any() == true; if (hasHistoryChanges || hasPersonHistoryChanges) { using (var historyRockContext = new RockContext()) { if (hasHistoryChanges) { HistoryService.SaveChanges(historyRockContext, typeof(ConnectionRequest), Rock.SystemGuid.Category.HISTORY_CONNECTION_REQUEST.AsGuid(), Entity.Id, HistoryChangeList, false, Entity.ModifiedByPersonAliasId); } if (hasPersonHistoryChanges) { var personId = Entity.PersonAlias?.PersonId ?? new PersonAliasService(rockContext).GetPersonId(Entity.PersonAliasId); if (personId.HasValue) { HistoryService.SaveChanges( historyRockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_CONNECTION_REQUEST.AsGuid(), personId.Value, PersonHistoryChangeList, "Request", typeof(ConnectionRequest), Entity.Id, false, Entity.ModifiedByPersonAliasId, rockContext.SourceOfChange); } } historyRockContext.SaveChanges(false); } } base.PostSave(); }
/// <summary> /// Called after the save operation has been executed /// </summary> /// <remarks> /// This method is only called if <see cref="M:Rock.Data.EntitySaveHook`1.PreSave" /> returns /// without error. /// </remarks> protected override void PostSave() { var rockContext = ( RockContext )this.RockContext; if (Entity.ConnectionStatus == null) { Entity.ConnectionStatus = new ConnectionStatusService(rockContext).Get(Entity.ConnectionStatusId); } if (Entity.ConnectionStatus != null && Entity.ConnectionStatus.AutoInactivateState && Entity.ConnectionState != ConnectionState.Inactive) { Entity.ConnectionState = ConnectionState.Inactive; rockContext.SaveChanges(); } if (Entity.ConnectionStatus.ConnectionStatusAutomations.Any()) { foreach (var connectionStatusAutomation in Entity.ConnectionStatus.ConnectionStatusAutomations) { bool isAutomationValid = true; if (connectionStatusAutomation.DataViewId.HasValue) { // Get the dataview configured for the connection request var dataViewService = new DataViewService(rockContext); var dataview = dataViewService.Get(connectionStatusAutomation.DataViewId.Value); if (dataview != null) { var dataViewGetQueryArgs = new DataViewGetQueryArgs { DbContext = rockContext }; isAutomationValid = dataview.GetQuery(dataViewGetQueryArgs).Any(a => a.Id == Entity.Id); } } if (isAutomationValid && connectionStatusAutomation.GroupRequirementsFilter != GroupRequirementsFilter.Ignore) { // Group Requirement can't be meet when either placement group or placement group role id is missing if (!Entity.AssignedGroupId.HasValue || !Entity.AssignedGroupMemberRoleId.HasValue) { isAutomationValid = false; } else { var isRequirementMeet = true; var group = new GroupService(rockContext).Get(Entity.AssignedGroupId.Value); var hasGroupRequirement = new GroupRequirementService(rockContext).Queryable().Where(a => (a.GroupId.HasValue && a.GroupId == group.Id) || (a.GroupTypeId.HasValue && a.GroupTypeId == group.GroupTypeId)).Any(); if (hasGroupRequirement) { var requirementsResults = group.PersonMeetsGroupRequirements( rockContext, Entity.PersonAlias.PersonId, Entity.AssignedGroupMemberRoleId.Value); if (requirementsResults != null && requirementsResults .Where(a => a.MeetsGroupRequirement != MeetsGroupRequirement.NotApplicable) .Any(r => r.MeetsGroupRequirement != MeetsGroupRequirement.Meets && r.MeetsGroupRequirement != MeetsGroupRequirement.MeetsWithWarning) ) { isRequirementMeet = false; } } // connection request based on if group requirement is meet or not is added to list for status update isAutomationValid = (connectionStatusAutomation.GroupRequirementsFilter == GroupRequirementsFilter.DoesNotMeet && !isRequirementMeet) || (connectionStatusAutomation.GroupRequirementsFilter == GroupRequirementsFilter.MustMeet && isRequirementMeet); } } if (isAutomationValid) { Entity.ConnectionStatusId = connectionStatusAutomation.DestinationStatusId; // disabled pre post processing in order to prevent circular loop that may arise due to status change. rockContext.SaveChanges(true); } } } if (HistoryChangeList?.Any() == true) { HistoryService.SaveChanges(rockContext, typeof(ConnectionRequest), Rock.SystemGuid.Category.HISTORY_CONNECTION_REQUEST.AsGuid(), Entity.Id, HistoryChangeList, true, Entity.ModifiedByPersonAliasId); } if (PersonHistoryChangeList?.Any() == true) { var personAlias = Entity.PersonAlias ?? new PersonAliasService(rockContext).Get(Entity.PersonAliasId); HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_CONNECTION_REQUEST.AsGuid(), personAlias.PersonId, PersonHistoryChangeList, "Request", typeof(ConnectionRequest), Entity.Id, true, Entity.ModifiedByPersonAliasId, rockContext.SourceOfChange); } base.PostSave(); }
/// <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); }