/// <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(); }