/// <summary> /// Creates the control(s) necessary for prompting user for a new value /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="id"></param> /// <returns> /// The control /// </returns> public override Control EditControl( Dictionary<string, ConfigurationValue> configurationValues, string id ) { var editControl = new RockDropDownList { ID = id }; editControl.Items.Add( new ListItem() ); var activityTypes = new ConnectionActivityTypeService( new RockContext() ) .Queryable().AsNoTracking() .OrderBy( s => s.ConnectionType.Name ) .ThenBy( s => s.Name ) .Select( s => new { s.Guid, s.Name, ConnectionTypeName = s.ConnectionType.Name } ) .ToList(); if ( activityTypes.Any() ) { foreach ( var activity in activityTypes ) { var listItem = new ListItem( activity.Name, activity.Guid.ToString().ToUpper() ); listItem.Attributes.Add( "OptionGroup", activity.ConnectionTypeName ); editControl.Items.Add( listItem ); } return editControl; } return null; }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection(Type entityType, string selection) { string s = "Activity"; var selectionConfig = SelectionConfig.Parse(selection); if (selectionConfig != null && selectionConfig.ConnectionActivityTypeGuid.HasValue) { var activityType = new ConnectionActivityTypeService(new RockContext()).Get(selectionConfig.ConnectionActivityTypeGuid.Value); var activityName = GetActivityName(activityType); var dateRangeString = string.Empty; if (selectionConfig.SlidingDateRangeDelimitedValues.IsNotNullOrWhiteSpace()) { var dateRange = SlidingDateRangePicker.FormatDelimitedValues(selectionConfig.SlidingDateRangeDelimitedValues); if (dateRangeString.IsNotNullOrWhiteSpace()) { dateRangeString += $" Date Range: {dateRangeString}"; } } s = string.Format( "Activity '{0}' {1} {2} times. {3}", activityName, selectionConfig.IntegerCompare.ConvertToString(), selectionConfig.MinimumCount, dateRangeString); } return(s); }
/// <summary> /// Gets the edit value as the IEntity.Id /// </summary> /// <param name="control">The control.</param> /// <param name="configurationValues">The configuration values.</param> /// <returns></returns> public int?GetEditValueAsEntityId(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues) { var guid = GetEditValue(control, configurationValues).AsGuid(); var item = new ConnectionActivityTypeService(new RockContext()).Get(guid); return(item != null ? item.Id : ( int? )null); }
/// <summary> /// Creates the control(s) necessary for prompting user for a new value /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="id"></param> /// <returns> /// The control /// </returns> public override Control EditControl(Dictionary <string, ConfigurationValue> configurationValues, string id) { var editControl = new RockDropDownList { ID = id }; editControl.Items.Add(new ListItem()); var activityTypes = new ConnectionActivityTypeService(new RockContext()) .Queryable().AsNoTracking() .OrderBy(s => s.ConnectionType.Name) .ThenBy(s => s.Name) .Select(s => new { s.Guid, s.Name, ConnectionTypeName = s.ConnectionType.Name }) .ToList(); if (activityTypes.Any()) { foreach (var activity in activityTypes) { var listItem = new ListItem(activity.Name, activity.Guid.ToString().ToUpper()); listItem.Attributes.Add("OptionGroup", activity.ConnectionTypeName); editControl.Items.Add(listItem); } return(editControl); } return(null); }
/// <summary> /// Sets the edit value from IEntity.Id value /// </summary> /// <param name="control">The control.</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="id">The identifier.</param> public void SetEditValueFromEntityId(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues, int?id) { var item = new ConnectionActivityTypeService(new RockContext()).Get(id ?? 0); var guidValue = item != null?item.Guid.ToString() : string.Empty; SetEditValue(control, configurationValues, guidValue); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); // Get the connection request ConnectionRequest request = null; Guid connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid(); var connectionRequestService = new ConnectionRequestService(rockContext); request = connectionRequestService.Get(connectionRequestGuid); if (request == null) { errorMessages.Add("Invalid Connection Request Attribute or Value!"); return(false); } // Get the opportunity ConnectionOpportunity opportunity = null; Guid opportunityTypeGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionOpportunityAttribute").AsGuid()).AsGuid(); opportunity = new ConnectionOpportunityService(rockContext).Get(opportunityTypeGuid); if (opportunity == null) { errorMessages.Add("Invalid Connection Opportunity Attribute or Value!"); return(false); } // Get the transfer note string note = GetAttributeValue(action, "TransferNote", true); if (request != null && opportunity != null) { request.ConnectionOpportunityId = opportunity.Id; var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid(); var transferredActivityId = new ConnectionActivityTypeService(rockContext) .Queryable() .Where(t => t.Guid == guid) .Select(t => t.Id) .FirstOrDefault(); ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = request.Id; connectionRequestActivity.ConnectionOpportunityId = opportunity.Id; connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId; connectionRequestActivity.Note = note; new ConnectionRequestActivityService(rockContext).Add(connectionRequestActivity); rockContext.SaveChanges(); } return(true); }
/// <summary> /// Creates the control(s) necessary for prompting user for a new value /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="id"></param> /// <returns> /// The control /// </returns> public override Control EditControl(Dictionary <string, ConfigurationValue> configurationValues, string id) { var includeInactive = false; int?connectionTypeFilterId = null; if (configurationValues != null) { includeInactive = configurationValues.ContainsKey(INCLUDE_INACTIVE_KEY) && configurationValues[INCLUDE_INACTIVE_KEY].Value.AsBoolean(); connectionTypeFilterId = configurationValues.ContainsKey(CONNECTION_TYPE_FILTER) ? configurationValues[CONNECTION_TYPE_FILTER].Value.AsIntegerOrNull() : null; } var activityTypes = new ConnectionActivityTypeService(new RockContext()) .Queryable().AsNoTracking() .Where(o => o.IsActive || includeInactive) .OrderBy(o => o.ConnectionType.Name) .ThenBy(o => o.Name) .Select(o => new { o.Guid, o.Name, o.ConnectionType }) .ToList(); var editControl = new RockDropDownList { ID = id }; editControl.Items.Add(new ListItem()); if (activityTypes.Any()) { foreach (var activityType in activityTypes) { if (connectionTypeFilterId != null && (activityType.ConnectionType == null || activityType.ConnectionType.Id != connectionTypeFilterId)) { continue; } var listItem = new ListItem(activityType.Name, activityType.Guid.ToString().ToUpper()); // Don't add an option group if there is a filter since that would be only one group. if (connectionTypeFilterId == null && activityType.ConnectionType != null) { listItem.Attributes.Add("OptionGroup", activityType.ConnectionType.Name); } editControl.Items.Add(listItem); } return(editControl); } return(null); }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; Guid?guid = value.AsGuidOrNull(); if (guid.HasValue) { var activityType = new ConnectionActivityTypeService(new RockContext()).Get(guid.Value); if (activityType != null) { formattedValue = activityType.Name; } } return(base.FormatValue(parentControl, formattedValue, configurationValues, condensed)); }
/// <summary> /// Handles the Click event of the btnTransferSave 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 btnTransferSave_Click( object sender, EventArgs e ) { using ( var rockContext = new RockContext() ) { var connectionRequestService = new ConnectionRequestService( rockContext ); var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext ); var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext ); var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() ); if ( connectionRequest != null ) { int? newOpportunityId = ddlTransferOpportunity.SelectedValueAsId(); int? newStatusId = ddlTransferStatus.SelectedValueAsId(); var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid(); var transferredActivityId = connectionActivityTypeService.Queryable() .Where( t => t.Guid == guid ) .Select( t => t.Id ) .FirstOrDefault(); if ( newOpportunityId.HasValue && newStatusId.HasValue && transferredActivityId > 0 ) { ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = newOpportunityId.Value; connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId; connectionRequestActivity.Note = tbTransferNote.Text; connectionRequestActivityService.Add( connectionRequestActivity ); connectionRequest.ConnectionOpportunityId = newOpportunityId.Value; connectionRequest.ConnectionStatusId = newStatusId.Value; connectionRequest.AssignedGroupId = null; connectionRequest.AssignedGroupMemberRoleId = null; connectionRequest.AssignedGroupMemberStatus = null; if ( cbClearConnector.Checked ) { connectionRequest.ConnectorPersonAliasId = null; } rockContext.SaveChanges(); pnlReadDetails.Visible = true; wpConnectionRequestActivities.Visible = true; wpConnectionRequestWorkflow.Visible = true; pnlTransferDetails.Visible = false; ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId ); } } } }
/// <summary> /// Handles the Click event of the lbConnect 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 lbConnect_Click( object sender, EventArgs e ) { using ( var rockContext = new RockContext() ) { var connectionRequestService = new ConnectionRequestService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext ); var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext ); var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() ); if ( connectionRequest != null && connectionRequest.PersonAlias != null && connectionRequest.ConnectionOpportunity != null ) { bool okToConnect = true; GroupMember groupMember = null; // Only do group member placement if the request has an assigned placement group, role, and status if ( connectionRequest.AssignedGroupId.HasValue && connectionRequest.AssignedGroupMemberRoleId.HasValue && connectionRequest.AssignedGroupMemberStatus.HasValue ) { var group = new GroupService( rockContext ).Get( connectionRequest.AssignedGroupId.Value ); if ( group != null ) { // Only attempt the add if person does not already exist in group with same role groupMember = groupMemberService.GetByGroupIdAndPersonIdAndGroupRoleId( connectionRequest.AssignedGroupId.Value, connectionRequest.PersonAlias.PersonId, connectionRequest.AssignedGroupMemberRoleId.Value ); if ( groupMember == null ) { groupMember = new GroupMember(); groupMember.PersonId = connectionRequest.PersonAlias.PersonId; groupMember.GroupId = connectionRequest.AssignedGroupId.Value; groupMember.GroupRoleId = connectionRequest.AssignedGroupMemberRoleId.Value; groupMember.GroupMemberStatus = connectionRequest.AssignedGroupMemberStatus.Value; foreach ( ListItem item in cblManualRequirements.Items ) { if ( !item.Selected && group.MustMeetRequirementsToAddMember.HasValue && group.MustMeetRequirementsToAddMember.Value ) { okToConnect = false; nbRequirementsErrors.Text = "Group Requirements have not been met. Please verify all of the requirements."; nbRequirementsErrors.Visible = true; break; } else { groupMember.GroupMemberRequirements.Add( new GroupMemberRequirement { GroupRequirementId = item.Value.AsInteger(), RequirementMetDateTime = RockDateTime.Now, LastRequirementCheckDateTime = RockDateTime.Now } ); } } if ( okToConnect ) { groupMemberService.Add( groupMember ); if ( !string.IsNullOrWhiteSpace( connectionRequest.AssignedGroupMemberAttributeValues ) ) { var savedValues = JsonConvert.DeserializeObject<Dictionary<string, string>>( connectionRequest.AssignedGroupMemberAttributeValues ); if ( savedValues != null ) { groupMember.LoadAttributes(); foreach ( var item in savedValues ) { groupMember.SetAttributeValue( item.Key, item.Value ); } } } } } } } if ( okToConnect ) { // ... but always record the connection activity and change the state to connected. var guid = Rock.SystemGuid.ConnectionActivityType.CONNECTED.AsGuid(); var connectedActivityId = connectionActivityTypeService.Queryable() .Where( t => t.Guid == guid ) .Select( t => t.Id ) .FirstOrDefault(); if ( connectedActivityId > 0 ) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = connectedActivityId; connectionRequestActivity.ConnectorPersonAliasId = CurrentPersonAliasId; connectionRequestActivityService.Add( connectionRequestActivity ); } connectionRequest.ConnectionState = ConnectionState.Connected; rockContext.SaveChanges(); if ( groupMember != null && !string.IsNullOrWhiteSpace( connectionRequest.AssignedGroupMemberAttributeValues ) ) { groupMember.SaveAttributeValues( rockContext ); } ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId ); } } } }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue( Control parentControl, string value, Dictionary<string, ConfigurationValue> configurationValues, bool condensed ) { string formattedValue = string.Empty; Guid? guid = value.AsGuidOrNull(); if (guid.HasValue) { var activityType = new ConnectionActivityTypeService( new RockContext() ).Get( guid.Value ); if ( activityType != null ) { formattedValue = activityType.Name; } } return base.FormatValue( parentControl, formattedValue, configurationValues, condensed ); }
/// <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 ) { if ( ! ppRequestor.PersonAliasId.HasValue ) { ShowErrorMessage( "Incomplete", "You must select a person to save a request." ); return; } if ( Page.IsValid ) { using ( var rockContext = new RockContext() ) { ConnectionRequestService connectionRequestService = new ConnectionRequestService( rockContext ); ConnectionRequest connectionRequest = null; int connectionRequestId = hfConnectionRequestId.ValueAsInt(); // if adding a new connection request if ( connectionRequestId.Equals( 0 ) ) { connectionRequest = new ConnectionRequest(); connectionRequest.ConnectionOpportunityId = hfConnectionOpportunityId.ValueAsInt(); if ( ddlCampus.SelectedValueAsId().HasValue ) { SetUserPreference( CAMPUS_SETTING, ddlCampus.SelectedValueAsId().Value.ToString() ); } } else { // load existing connection request connectionRequest = connectionRequestService.Get( connectionRequestId ); } var personAliasService = new PersonAliasService( rockContext ); int? oldConnectorPersonAliasId = connectionRequest.ConnectorPersonAliasId; int? newConnectorPersonId = ddlConnectorEdit.SelectedValueAsId(); int? newConnectorPersonAliasId = newConnectorPersonId.HasValue ? personAliasService.GetPrimaryAliasId( newConnectorPersonId.Value ) : (int?)null; connectionRequest.ConnectorPersonAliasId = newConnectorPersonAliasId; connectionRequest.PersonAlias = personAliasService.Get( ppRequestor.PersonAliasId.Value ); connectionRequest.ConnectionState = rblState.SelectedValueAsEnum<ConnectionState>(); connectionRequest.ConnectionStatusId = rblStatus.SelectedValueAsId().Value; if ( ddlCampus.SelectedValueAsId().HasValue ) { connectionRequest.CampusId = ddlCampus.SelectedValueAsId().Value; } connectionRequest.AssignedGroupId = ddlPlacementGroup.SelectedValueAsId(); connectionRequest.AssignedGroupMemberRoleId = ddlPlacementGroupRole.SelectedValueAsInt(); connectionRequest.AssignedGroupMemberStatus = ddlPlacementGroupStatus.SelectedValueAsEnumOrNull<GroupMemberStatus>(); connectionRequest.AssignedGroupMemberAttributeValues = GetGroupMemberAttributeValues(); connectionRequest.Comments = tbComments.Text.ScrubHtmlAndConvertCrLfToBr(); connectionRequest.FollowupDate = dpFollowUp.SelectedDate; if ( !Page.IsValid ) { return; } // if the connectionRequest IsValue is false, and the UI controls didn't report any errors, it is probably // because the custom rules of ConnectionRequest didn't pass. // So, make sure a message is displayed in the validation summary. cvConnectionRequest.IsValid = connectionRequest.IsValid; if ( !cvConnectionRequest.IsValid ) { cvConnectionRequest.ErrorMessage = connectionRequest.ValidationResults.Select( a => a.ErrorMessage ).ToList().AsDelimited( "<br />" ); return; } if ( connectionRequest.Id.Equals( 0 ) ) { connectionRequestService.Add( connectionRequest ); } rockContext.SaveChanges(); if ( newConnectorPersonAliasId.HasValue && !newConnectorPersonAliasId.Equals( oldConnectorPersonAliasId ) ) { var guid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); var assignedActivityId = new ConnectionActivityTypeService( rockContext ).Queryable() .Where( t => t.Guid == guid ) .Select( t => t.Id ) .FirstOrDefault(); if ( assignedActivityId > 0 ) { var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext ); var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId; connectionRequestActivity.ConnectorPersonAliasId = newConnectorPersonAliasId; connectionRequestActivityService.Add( connectionRequestActivity ); rockContext.SaveChanges(); } } var qryParams = new Dictionary<string, string>(); qryParams["ConnectionRequestId"] = connectionRequest.Id.ToString(); qryParams["ConnectionOpportunityId"] = connectionRequest.ConnectionOpportunityId.ToString(); NavigateToPage( RockPage.Guid, qryParams ); } } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { ConnectionType connectionType; using ( var rockContext = new RockContext() ) { if ( StatusesState.Any( s => s.IsDefault ) && ActivityTypesState.Any() ) { ConnectionTypeService connectionTypeService = new ConnectionTypeService( rockContext ); ConnectionActivityTypeService connectionActivityTypeService = new ConnectionActivityTypeService( rockContext ); ConnectionStatusService connectionStatusService = new ConnectionStatusService( rockContext ); ConnectionWorkflowService connectionWorkflowService = new ConnectionWorkflowService( rockContext ); AttributeService attributeService = new AttributeService( rockContext ); AttributeQualifierService qualifierService = new AttributeQualifierService( rockContext ); int connectionTypeId = int.Parse( hfConnectionTypeId.Value ); if ( connectionTypeId == 0 ) { connectionType = new ConnectionType(); connectionTypeService.Add( connectionType ); } else { connectionType = connectionTypeService.Queryable( "ConnectionActivityTypes, ConnectionWorkflows" ).Where( c => c.Id == connectionTypeId ).FirstOrDefault(); var uiWorkflows = WorkflowsState.Select( l => l.Guid ); foreach ( var connectionWorkflow in connectionType.ConnectionWorkflows.Where( l => !uiWorkflows.Contains( l.Guid ) ).ToList() ) { connectionType.ConnectionWorkflows.Remove( connectionWorkflow ); connectionWorkflowService.Delete( connectionWorkflow ); } var uiActivityTypes = ActivityTypesState.Select( r => r.Guid ); foreach ( var connectionActivityType in connectionType.ConnectionActivityTypes.Where( r => !uiActivityTypes.Contains( r.Guid ) ).ToList() ) { connectionType.ConnectionActivityTypes.Remove( connectionActivityType ); connectionActivityTypeService.Delete( connectionActivityType ); } var uiStatuses = StatusesState.Select( r => r.Guid ); foreach ( var connectionStatus in connectionType.ConnectionStatuses.Where( r => !uiStatuses.Contains( r.Guid ) ).ToList() ) { connectionType.ConnectionStatuses.Remove( connectionStatus ); connectionStatusService.Delete( connectionStatus ); } } connectionType.Name = tbName.Text; connectionType.Description = tbDescription.Text; connectionType.IconCssClass = tbIconCssClass.Text; connectionType.DaysUntilRequestIdle = nbDaysUntilRequestIdle.Text.AsInteger(); connectionType.EnableFutureFollowup = cbFutureFollowUp.Checked; connectionType.EnableFullActivityList = cbFullActivityList.Checked; connectionType.RequiresPlacementGroupToConnect = cbRequiresPlacementGroup.Checked; foreach ( var connectionActivityTypeState in ActivityTypesState ) { ConnectionActivityType connectionActivityType = connectionType.ConnectionActivityTypes.Where( a => a.Guid == connectionActivityTypeState.Guid ).FirstOrDefault(); if ( connectionActivityType == null ) { connectionActivityType = new ConnectionActivityType(); connectionType.ConnectionActivityTypes.Add( connectionActivityType ); } connectionActivityType.CopyPropertiesFrom( connectionActivityTypeState ); } foreach ( var connectionStatusState in StatusesState ) { ConnectionStatus connectionStatus = connectionType.ConnectionStatuses.Where( a => a.Guid == connectionStatusState.Guid ).FirstOrDefault(); if ( connectionStatus == null ) { connectionStatus = new ConnectionStatus(); connectionType.ConnectionStatuses.Add( connectionStatus ); } connectionStatus.CopyPropertiesFrom( connectionStatusState ); connectionStatus.ConnectionTypeId = connectionType.Id; } foreach ( ConnectionWorkflow connectionWorkflowState in WorkflowsState ) { ConnectionWorkflow connectionWorkflow = connectionType.ConnectionWorkflows.Where( a => a.Guid == connectionWorkflowState.Guid ).FirstOrDefault(); if ( connectionWorkflow == null ) { connectionWorkflow = new ConnectionWorkflow(); connectionType.ConnectionWorkflows.Add( connectionWorkflow ); } else { connectionWorkflowState.Id = connectionWorkflow.Id; connectionWorkflowState.Guid = connectionWorkflow.Guid; } connectionWorkflow.CopyPropertiesFrom( connectionWorkflowState ); connectionWorkflow.ConnectionTypeId = connectionTypeId; } if ( !connectionType.IsValid ) { // Controls will render the error messages return; } // need WrapTransaction due to Attribute saves rockContext.WrapTransaction( () => { rockContext.SaveChanges(); /* Save Attributes */ string qualifierValue = connectionType.Id.ToString(); SaveAttributes( new ConnectionOpportunity().TypeId, "ConnectionTypeId", qualifierValue, AttributesState, rockContext ); connectionType = connectionTypeService.Get( connectionType.Id ); if ( connectionType != null ) { if ( !connectionType.IsAuthorized( Authorization.VIEW, CurrentPerson ) ) { connectionType.AllowPerson( Authorization.VIEW, CurrentPerson, rockContext ); } if ( !connectionType.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { connectionType.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext ); } if ( !connectionType.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ) ) { connectionType.AllowPerson( Authorization.ADMINISTRATE, CurrentPerson, rockContext ); } } } ); ConnectionWorkflowService.FlushCachedTriggers(); var qryParams = new Dictionary<string, string>(); qryParams["ConnectionTypeId"] = connectionType.Id.ToString(); NavigateToPage( RockPage.Guid, qryParams ); } else { nbRequired.Visible = true; } } }
private void LaunchWorkflow( RockContext rockContext, ConnectionWorkflow connectionWorkflow, string name ) { ConnectionRequestActivity connectionRequestActivity = null; if ( ConnectionRequestActivityGuid.HasValue ) { connectionRequestActivity = new ConnectionRequestActivityService( rockContext ).Get( ConnectionRequestActivityGuid.Value ); } var workflowTypeService = new WorkflowTypeService( rockContext ); var workflowType = workflowTypeService.Get( connectionWorkflow.WorkflowTypeId.Value ); if ( workflowType != null ) { var workflow = Rock.Model.Workflow.Activate( workflowType, name ); if ( workflow.AttributeValues != null ) { if ( workflow.AttributeValues.ContainsKey( "ConnectionOpportunity" ) ) { var connectionOpportunity = new ConnectionOpportunityService( rockContext ).Get( ConnectionOpportunityId.Value ); if ( connectionOpportunity != null ) { workflow.AttributeValues["ConnectionOpportunity"].Value = connectionOpportunity.Guid.ToString(); } } if ( workflow.AttributeValues.ContainsKey( "ConnectionType" ) ) { var connectionType = new ConnectionTypeService( rockContext ).Get( ConnectionTypeId.Value ); if ( connectionType != null ) { workflow.AttributeValues["ConnectionType"].Value = connectionType.Guid.ToString(); } } if ( workflow.AttributeValues.ContainsKey( "ConnectionRequestActivity" ) ) { if ( connectionRequestActivity != null ) { workflow.AttributeValues["ConnectionRequestActivity"].Value = connectionRequestActivity.Guid.ToString(); } } if ( workflow.AttributeValues.ContainsKey( "ConnectionActivityType" ) ) { var connectionActivityType = new ConnectionActivityTypeService( rockContext ).Get( ConnectionActivityTypeId ); if ( connectionActivityType != null ) { workflow.AttributeValues["ConnectionActivityType"].Value = connectionActivityType.Guid.ToString(); } } } List<string> workflowErrors; new WorkflowService( rockContext ).Process( workflow, connectionRequestActivity, out workflowErrors ); if ( workflow.Id != 0 ) { ConnectionRequestWorkflow connectionRequestWorkflow = new ConnectionRequestWorkflow(); connectionRequestWorkflow.ConnectionRequestId = connectionRequestActivity.ConnectionRequestId; connectionRequestWorkflow.WorkflowId = workflow.Id; connectionRequestWorkflow.ConnectionWorkflowId = connectionWorkflow.Id; connectionRequestWorkflow.TriggerType = connectionWorkflow.TriggerType; connectionRequestWorkflow.TriggerQualifier = connectionWorkflow.QualifierValue; new ConnectionRequestWorkflowService( rockContext ).Add( connectionRequestWorkflow ); rockContext.SaveChanges(); } } }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages ) { errorMessages = new List<string>(); // Get the connection request ConnectionRequest request = null; Guid connectionRequestGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionRequestAttribute" ).AsGuid() ).AsGuid(); var connectionRequestService = new ConnectionRequestService( rockContext ); request = connectionRequestService.Get( connectionRequestGuid ); if ( request == null ) { errorMessages.Add( "Invalid Connection Request Attribute or Value!" ); return false; } // Get the opportunity ConnectionOpportunity opportunity = null; Guid opportunityTypeGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionOpportunityAttribute" ).AsGuid() ).AsGuid(); opportunity = new ConnectionOpportunityService( rockContext ).Get( opportunityTypeGuid ); if ( opportunity == null ) { errorMessages.Add( "Invalid Connection Opportunity Attribute or Value!" ); return false; } // Get the tranfer note string note = GetAttributeValue( action, "TransferNote", true ); if ( request != null && opportunity != null ) { request.ConnectionOpportunityId = opportunity.Id; var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid(); var transferredActivityId = new ConnectionActivityTypeService( rockContext ) .Queryable() .Where( t => t.Guid == guid ) .Select( t => t.Id ) .FirstOrDefault(); ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = request.Id; connectionRequestActivity.ConnectionOpportunityId = opportunity.Id; connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId; connectionRequestActivity.Note = note; new ConnectionRequestActivityService( rockContext ).Add( connectionRequestActivity ); rockContext.SaveChanges(); } return true; }
/// <summary> /// Assigns the connection requests from the SelectedCampaign's entity set. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="selectedCampaignItem">The selected campaign item.</param> /// <param name="numberOfRequestsRemaining">The number of requests remaining.</param> /// <param name="connectorPerson">The connector person.</param> private static void AssignConnectionRequestsFromEntitySet(RockContext rockContext, CampaignItem selectedCampaignItem, ref int numberOfRequestsRemaining, Person connectorPerson) { var opportunityService = new ConnectionOpportunityService(rockContext); ConnectionOpportunity opportunity = opportunityService.Get(selectedCampaignItem.OpportunityGuid); if (opportunity == null || !opportunity.IsActive) { return; } int?defaultStatusId = opportunity.ConnectionType.ConnectionStatuses .Where(s => s.IsDefault) .Select(s => ( int? )s.Id) .FirstOrDefault(); // If opportunity doesn't have a default status, something is wrong if (defaultStatusId == null) { return; } var connectorCampusIds = GetConnectorCampusIds(selectedCampaignItem, connectorPerson); var connectionRequestService = new ConnectionRequestService(rockContext); var connectionRequestActivityService = new ConnectionRequestActivityService(rockContext); // get previous connections for the connector that have the same campus of the connector, or if the person's campus or connector person's campus is null var previousConnectedPersonIdsForCurrentPerson = connectionRequestService.Queryable() .Where(a => a.ConnectionOpportunityId == opportunity.Id) .Where(a => a.ConnectorPersonAlias.PersonId == connectorPerson.Id) .Where(a => (a.CampusId == null) || connectorCampusIds.Any(connectorCampusId => connectorCampusId == null || a.CampusId.Value == connectorCampusId)) .Select(a => a.PersonAlias.PersonId).Distinct().ToList(); var entitySetId = CampaignConnectionHelper.GetEntitySet(selectedCampaignItem); var entitySetItemService = new EntitySetItemService(rockContext); var entitySetItemList = entitySetItemService.Queryable().Where(a => a.EntitySetId == entitySetId).OrderBy(a => a.Order).Select(a => new { PersonId = a.EntityId, EntityItemOrder = a.Order }).ToList(); if (selectedCampaignItem.PreferPreviousConnector) { // sort them by any where the current person was assigned to this person before entitySetItemList = entitySetItemList .OrderBy(a => previousConnectedPersonIdsForCurrentPerson.Any(x => x == a.PersonId)) .ThenBy(a => a.EntityItemOrder).ToList(); } else { entitySetItemList = entitySetItemList.OrderBy(a => a.EntityItemOrder).ToList(); } var personService = new PersonService(rockContext); // get the last connection datetime. var lastConnectionDateTime = RockDateTime.Now.AddDays(-selectedCampaignItem.DaysBetweenConnection); // if DaysBetweenConnection is 0 then check for connection request for any time period. if (selectedCampaignItem.DaysBetweenConnection == default(int)) { lastConnectionDateTime = DateTime.MinValue; } foreach (var entitySetItem in entitySetItemList) { var entitySetPerson = personService.Get(entitySetItem.PersonId); if (entitySetPerson == null) { continue; } var entitySetPersonPrimaryCampusId = entitySetPerson.PrimaryCampusId; bool validCampus = IsValidCampus(connectorCampusIds, entitySetPersonPrimaryCampusId); if (!validCampus) { continue; } // double check that they haven't already been added bool personAlreadyHasConnectionRequest = PersonAlreadyHasConnectionRequest(opportunity.Id, rockContext, lastConnectionDateTime, entitySetPerson.Id); if (personAlreadyHasConnectionRequest) { continue; } var connectionRequest = new ConnectionRequest(); connectionRequest.ConnectionOpportunityId = opportunity.Id; /* * 3/30/2020 - NA * * When setting the connection request's Requester, we have to use the PrimaryAlias * to set the connectionRequest.PersonAlias property because the ConnectionRequestChangeTransaction * https://github.com/SparkabilityGroup/Rock/blob/a556a9285b7fdfe5594441286242f4feaa5847f2/Rock/Transactions/ConnectionRequestChangeTransaction.cs#L123 * (which handles triggered workflows) expects it. Also, it needs to be tracked by * the current rockContext... hence the change from GetAsNoTracking() to just Get() above: * var entitySetPerson = personService.Get( entitySetItem.PersonId ); * * In other words, this will not work correctly: * connectionRequest.PersonAliasId = entitySetPerson.PrimaryAliasId.Value; * * Reason: This plug-in cannot change Rock core assembly code. */ connectionRequest.PersonAlias = entitySetPerson.PrimaryAlias; connectionRequest.ConnectionState = ConnectionState.Active; connectionRequest.ConnectorPersonAliasId = connectorPerson.PrimaryAliasId; connectionRequest.CampusId = entitySetPersonPrimaryCampusId; connectionRequest.ConnectionStatusId = defaultStatusId.Value; if (selectedCampaignItem.RequestCommentsLavaTemplate.IsNotNullOrWhiteSpace()) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", entitySetPerson); mergeFields.Add("Family", entitySetPerson.GetFamily()); connectionRequest.Comments = selectedCampaignItem.RequestCommentsLavaTemplate.ResolveMergeFields(mergeFields); } connectionRequestService.Add(connectionRequest); var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid); if (assignedActivityId.HasValue) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequest = connectionRequest; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value; connectionRequestActivity.ConnectorPersonAliasId = connectorPerson.PrimaryAliasId; connectionRequestActivityService.Add(connectionRequestActivity); } numberOfRequestsRemaining--; if (numberOfRequestsRemaining <= 0) { break; } } }
/// <summary> /// Trigger Future Followup Workflow /// </summary> /// <param name="context">The context.</param> /// <param name="futureFollowupDateWorkflows">The future follow-up date workflows.</param> /// <returns></returns> private string TriggerFutureFollowupWorkFlow(IJobExecutionContext context, List <ConnectionWorkflow> futureFollowupDateWorkflows) { try { JobDataMap dataMap = context.JobDetail.JobDataMap; context.UpdateLastStatusMessage($"Processing future follow-up workFlows."); int recordsUpdated = 0; int triggerWorkflow = 0; int recordsWithError = 0; var rockContext = new RockContext(); DateTime midnightToday = RockDateTime.Today.AddDays(1); var connectionRequestService = new ConnectionRequestService(rockContext); var eligibleConnectionRequests = connectionRequestService .Queryable("ConnectionRequestWorkflows") .AsNoTracking() .Where(c => c.ConnectionState == ConnectionState.FutureFollowUp && c.FollowupDate.HasValue && c.FollowupDate < midnightToday) .ToList(); foreach (var connectionRequest in eligibleConnectionRequests) { try { using (var updateRockContext = new RockContext()) { // increase the timeout just in case. updateRockContext.Database.CommandTimeout = 180; updateRockContext.SourceOfChange = SOURCE_OF_CHANGE; var connectionOpportunity = connectionRequest.ConnectionOpportunity; if (connectionOpportunity != null) { var opportunityWorkflows = futureFollowupDateWorkflows .Where(w => (w.ConnectionOpportunityId.HasValue && w.ConnectionOpportunityId.Value == connectionOpportunity.Id) || (w.ConnectionTypeId.HasValue && w.ConnectionTypeId.Value == connectionOpportunity.ConnectionTypeId)); foreach (var connectionWorkflow in opportunityWorkflows) { LaunchWorkflow(updateRockContext, connectionRequest, connectionWorkflow, ConnectionWorkflowTriggerType.FutureFollowupDateReached.ConvertToString()); triggerWorkflow += 1; } updateRockContext.ConnectionRequests.Attach(connectionRequest); connectionRequest.ConnectionState = ConnectionState.Active; var guid = Rock.SystemGuid.ConnectionActivityType.FUTURE_FOLLOWUP_COMPLETE.AsGuid(); var futureFollowupCompleteActivityId = new ConnectionActivityTypeService(rockContext) .Queryable() .Where(t => t.Guid == guid) .Select(t => t.Id) .FirstOrDefault(); ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = futureFollowupCompleteActivityId; new ConnectionRequestActivityService(updateRockContext).Add(connectionRequestActivity); updateRockContext.SaveChanges(); recordsUpdated += 1; } } } catch (Exception ex) { // Log exception and keep on trucking. ExceptionLogService.LogException(new Exception($"Exception occurred trying to trigger future followup workFlow:{connectionRequest.Id}.", ex), _httpContext); recordsWithError += 1; } } // Format the result message string result = $"{recordsUpdated:N0} connection request records triggered {triggerWorkflow} workflows."; if (recordsWithError > 0) { result += $"{recordsWithError:N0} records logged an exception."; } return(result); } catch (Exception ex) { // Log exception and return the exception messages. ExceptionLogService.LogException(ex, _httpContext); return(ex.Messages().AsDelimited("; ")); } }
/// <summary> /// Loads the ConnectionRequests. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadConnectionRequest(CSVInstance csvData) { var lookupContext = new RockContext(); var connectionTypes = new ConnectionTypeService(lookupContext).Queryable().ToList(); var activityTypes = new ConnectionActivityTypeService(lookupContext).Queryable().ToList(); var opportunities = new ConnectionOpportunityService(lookupContext).Queryable().ToList(); var statuses = new ConnectionStatusService(lookupContext).Queryable().ToList(); var requests = new ConnectionRequestService(lookupContext).Queryable().ToList(); var newRequests = new List <ConnectionRequest>(); var newActivities = new List <ConnectionRequestActivity>(); var completedItems = 0; ReportProgress(0, string.Format("Verifying connection request import ({0:N0} already imported).", requests.Count(n => n.ForeignKey != null))); ConnectionType connectionType = null; ConnectionOpportunity opportunity = null; string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var oForeignKey = row[OpportunityForeignKey] as string; var oName = row[OpportunityName] as string; var cType = row[ConnectionType] as string; var oDescription = row[OpportunityDescription] as string; var oActive = row[OpportunityActive].AsBoolean(); var oCreatedDate = row[OpportunityCreated].AsDateTime(); var oModifiedDate = row[OpportunityModified].AsDateTime(); var rForeignKey = row[RequestForeignKey] as string; var rPersonId = row[RequestPersonId].AsIntegerOrNull(); var rConnectorId = row[RequestConnectorId].AsIntegerOrNull(); var rCreatedDate = row[RequestCreated].AsDateTime(); var rModifiedDate = row[RequestModified].AsDateTime(); var rStatus = row[RequestStatus] as string; var rState = row[RequestState].AsIntegerOrNull(); var rComments = row[RequestComments] as string; var rFollowUp = row[RequestFollowUp].AsDateTime(); var aType = row[ActivityType] as string; var aNote = row[ActivityNote] as string; var aCreatedDate = row[ActivityDate].AsDateTime(); var aConnectorId = row[ActivityConnectorId].AsIntegerOrNull(); // lookup or reuse connection type if (connectionType == null || !connectionType.Name.Equals(cType, StringComparison.OrdinalIgnoreCase)) { connectionType = connectionTypes.FirstOrDefault(t => t.Name.Equals(cType, StringComparison.OrdinalIgnoreCase)); } if (connectionType == null) { connectionType = AddConnectionType(lookupContext, cType); connectionTypes.Add(connectionType); } if (connectionType != null && !string.IsNullOrWhiteSpace(oName) && GetPersonKeys(rPersonId) != null) { // lookup, reuse, or create connection opportunity if (opportunity == null || !opportunity.ForeignKey.Equals(oForeignKey, StringComparison.OrdinalIgnoreCase)) { opportunity = opportunities.FirstOrDefault(o => (o.ForeignKey != null && o.ForeignKey.Equals(oForeignKey, StringComparison.OrdinalIgnoreCase)) || o.Name.Equals(oName, StringComparison.OrdinalIgnoreCase)); } if (opportunity == null) { opportunity = AddConnectionOpportunity(lookupContext, connectionType.Id, oCreatedDate, oName, oDescription, oActive, oForeignKey); opportunities.Add(opportunity); } else if (opportunity.ForeignKey == null) { opportunity.ForeignKey = oForeignKey; opportunity.ForeignId = oForeignKey.AsIntegerOrNull(); lookupContext.SaveChanges(); } // lookup, reuse, or create connection request var requestStatus = statuses.FirstOrDefault(s => s.Name.Equals(rStatus, StringComparison.OrdinalIgnoreCase) && s.ConnectionTypeId.HasValue && s.ConnectionTypeId.Value == connectionType.Id); if (requestStatus == null) { requestStatus = AddConnectionStatus(lookupContext, rStatus, connectionType.Id); statuses.Add(requestStatus); } var requestor = GetPersonKeys(rPersonId); var requestConnector = rConnectorId.HasValue ? GetPersonKeys(rConnectorId) : null; var request = requests.FirstOrDefault(r => r.ForeignKey != null && r.ForeignKey.Equals(rForeignKey, StringComparison.OrdinalIgnoreCase)) ?? newRequests.FirstOrDefault(r => r.ForeignKey != null && r.ForeignKey.Equals(rForeignKey, StringComparison.OrdinalIgnoreCase)); if (request == null && requestor != null && requestStatus != null) { request = AddConnectionRequest(opportunity, rForeignKey, rCreatedDate, rModifiedDate, requestStatus.Id, ( ConnectionState )rState, rComments, rFollowUp, requestor.PersonAliasId, requestConnector?.PersonAliasId); newRequests.Add(request); } // create activity if (!string.IsNullOrWhiteSpace(aType)) { var activityConnector = aConnectorId.HasValue ? GetPersonKeys(aConnectorId) : null; var activityType = activityTypes.FirstOrDefault(t => t.Name.Equals(aType, StringComparison.OrdinalIgnoreCase)); if (request != null && activityType != null) { var activity = AddConnectionActivity(opportunity.Id, aNote, aCreatedDate, activityConnector?.PersonAliasId, activityType.Id, rForeignKey); if (request.Id > 0) { activity.ConnectionRequestId = request.Id; newActivities.Add(activity); } else { request.ConnectionRequestActivities.Add(activity); } } } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} requests processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SaveConnectionRequests(newRequests, newActivities); ReportPartialProgress(); requests.AddRange(newRequests); newRequests.Clear(); newActivities.Clear(); } } } if (newRequests.Count > 0 || newActivities.Count > 0) { SaveConnectionRequests(newRequests, newActivities); } ReportProgress(100, string.Format("Finished connection request import: {0:N0} requests imported.", completedItems)); return(completedItems); }
/// <summary> /// Translates the individual contact notes. /// </summary> /// <param name="tableData">The table data.</param> /// <param name="totalRows">The total rows.</param> public void TranslateIndividualContactNotes(IQueryable <Row> tableData, long totalRows = 0) { var lookupContext = new RockContext(); var activityTypeService = new ConnectionActivityTypeService(lookupContext); var connectedActivityType = activityTypeService.Get(Rock.SystemGuid.ConnectionActivityType.CONNECTED.AsGuid()); var assignedActivityType = activityTypeService.Get(Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid()); var importedNotes = new NoteService(lookupContext).Queryable().Where(n => n.ForeignId != null) .ToDictionary(n => n.ForeignId, n => n.Id); var importedConnectionRequests = new ConnectionRequestService(lookupContext).Queryable().Where(r => r.ForeignId != null) .ToDictionary(r => r.ForeignId, r => new { Id = r.Id, OpportunityId = r.ConnectionOpportunityId, ConnectorId = r.ConnectorPersonAliasId, State = r.ConnectionState }); var importedPrayerRequests = new PrayerRequestService(lookupContext).Queryable().Where(r => r.ForeignId != null) .ToDictionary(r => r.ForeignId, r => r.Id); int?confidentialNoteTypeId = null; var noteList = new List <Note>(); var activityList = new List <ConnectionRequestActivity>(); if (totalRows == 0) { totalRows = tableData.Count(); } var completedItems = 0; var percentage = (totalRows - 1) / 100 + 1; ReportProgress(0, $"Verifying contact notes ({totalRows:N0} found, {importedNotes.Count:N0} already exist)."); foreach (var row in tableData.Where(r => r != null)) { var userId = row["UserID"] as int?; var individualId = row["IndividualID"] as int?; var relatedForeignKey = row["ContactInstItemID"] as int?; var itemForeignKey = row["IndividualContactID"] as int?; var createdDate = row["IndividualContactDatetime"] as DateTime?; var noteText = row["IndividualContactNote"] as string; var confidentialText = row["ConfidentialNote"] as string; var personKeys = GetPersonKeys(individualId, null); int?creatorAliasId = null; if (userId.HasValue && PortalUsers.ContainsKey((int)userId)) { creatorAliasId = PortalUsers[(int)userId]; } if (personKeys != null && (!string.IsNullOrWhiteSpace(noteText) || !string.IsNullOrWhiteSpace(confidentialText))) { // this is a connection request comment if (importedConnectionRequests.ContainsKey(relatedForeignKey)) { var parentRequest = importedConnectionRequests[relatedForeignKey]; var activityType = parentRequest.State == ConnectionState.Active ? assignedActivityType : connectedActivityType; if (parentRequest != null && activityType != null) { var requestActivity = AddConnectionActivity(parentRequest.OpportunityId, noteText, createdDate, creatorAliasId ?? parentRequest.ConnectorId, activityType.Id, relatedForeignKey.ToString()); requestActivity.ConnectionRequestId = parentRequest.Id; activityList.Add(requestActivity); } } else // this is a new note or prayer request comment { var noteId = 0; var noteEntityId = personKeys.PersonId; var noteEntityTypeId = PersonEntityTypeId; var noteTypeId = PersonalNoteTypeId; // add a confidential note if (!string.IsNullOrWhiteSpace(confidentialText)) { var confidential = AddEntityNote(lookupContext, noteEntityTypeId, noteEntityId, string.Empty, confidentialText, false, false, "Confidential Note", confidentialNoteTypeId, false, createdDate, relatedForeignKey.ToString()); confidentialNoteTypeId = confidential.NoteTypeId; noteList.Add(confidential); } // this is new or an update to timeline note if (importedNotes.ContainsKey(relatedForeignKey)) { noteId = importedNotes[relatedForeignKey]; } // this is a prayer request comment else if (importedPrayerRequests.ContainsKey(relatedForeignKey)) { noteEntityTypeId = PrayerRequestTypeId; noteEntityId = importedPrayerRequests[relatedForeignKey]; noteTypeId = PrayerNoteTypeId; } // add the note text if (!string.IsNullOrWhiteSpace(noteText)) { var note = AddEntityNote(lookupContext, noteEntityTypeId, noteEntityId, string.Empty, noteText, false, false, null, noteTypeId, false, createdDate, itemForeignKey.ToString()); note.Id = noteId; noteList.Add(note); } } completedItems++; if (completedItems % percentage < 1) { var percentComplete = completedItems / percentage; ReportProgress(percentComplete, $"{completedItems:N0} notes imported ({percentComplete}% complete)."); } else if (completedItems % ReportingNumber < 1) { SaveNotes(noteList); SaveActivities(activityList); ReportPartialProgress(); noteList.Clear(); activityList.Clear(); } } } if (noteList.Any() || activityList.Any()) { SaveNotes(noteList); SaveActivities(activityList); } ReportProgress(100, $"Finished contact note import: {completedItems:N0} notes imported."); }
/// <summary> /// Add Connection Request to Context /// </summary> /// <param name="entityItemPersonAlias">The entity set item person alias.</param> /// <param name="requestCommentsLavaTemplate">The connection opportunity.</param> /// <param name="connectionOpportunityId">The connection opportunity indentifier.</param> /// <param name="connectionStatusId">The connection status identifier.</param> /// <param name="connectorPersonAliasId">The connector person alias indentifier.</param> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private void CreateConnectionRequest(PersonAlias entityItemPersonAlias, string requestCommentsLavaTemplate, int connectionOpportunityId, int?connectionStatusId, int?connectorPersonAliasId, RockContext rockContext) { var defaultCampus = entityItemPersonAlias.Person.GetCampus(); using (var insertRockContext = new RockContext()) { try { /* * 3/30/2020 - NA * * When setting the connection request's Requester, we have to use the PrimaryAlias * to set the connectionRequest.PersonAlias property because the ConnectionRequestChangeTransaction * https://github.com/SparkabilityGroup/Rock/blob/a556a9285b7fdfe5594441286242f4feaa5847f2/Rock/Transactions/ConnectionRequestChangeTransaction.cs#L123 * (which handles triggered workflows) expects it. Also, it needs to be tracked by * the current rockContext... * * In other words, this will not work correctly: * PersonAliasId = personAlias.Id, * * Reason: This plug-in cannot change Rock core assembly code. */ var personPrimaryAlias = new PersonAliasService(insertRockContext).GetPrimaryAlias(entityItemPersonAlias.PersonId); var connectionRequestActivityService = new ConnectionRequestActivityService(insertRockContext); var insertConnectionRequestService = new ConnectionRequestService(insertRockContext); var connectionRequest = new ConnectionRequest() { ConnectionOpportunityId = connectionOpportunityId, PersonAlias = personPrimaryAlias, ConnectionState = ConnectionState.Active, ConnectorPersonAliasId = connectorPersonAliasId, CampusId = defaultCampus?.Id, ConnectionStatusId = connectionStatusId.Value, }; if (requestCommentsLavaTemplate.IsNotNullOrWhiteSpace()) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", entityItemPersonAlias.Person); mergeFields.Add("Family", entityItemPersonAlias.Person.GetFamily()); connectionRequest.Comments = requestCommentsLavaTemplate.ResolveMergeFields(mergeFields); } insertConnectionRequestService.Add(connectionRequest); if (connectorPersonAliasId.HasValue) { var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid); if (assignedActivityId.HasValue) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequest = connectionRequest; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value; connectionRequestActivity.ConnectorPersonAliasId = connectorPersonAliasId; connectionRequestActivityService.Add(connectionRequestActivity); } } insertRockContext.SaveChanges(); } catch (Exception ex) { // Log exception and keep on trucking. var exception = new Exception($"Exception occurred trying to create connection request:{entityItemPersonAlias.Id}.", ex); createConnectionRequestExceptions.Add(exception); ExceptionLogService.LogException(exception, null); } } }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); var mergeFields = GetMergeFields(action); // Get the connection request ConnectionRequest connectionRequest = null; Guid connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid(); connectionRequest = new ConnectionRequestService(rockContext).Get(connectionRequestGuid); if (connectionRequest == null) { errorMessages.Add("Invalid Connection Request Attribute or Value!"); return(false); } // Get the connector int? personAliasId = null; Guid?personAttributeGuid = GetAttributeValue(action, "PersonAttribute").AsGuidOrNull(); if (personAttributeGuid.HasValue) { Guid?personAliasGuid = action.GetWorklowAttributeValue(personAttributeGuid.Value).AsGuidOrNull(); if (personAliasGuid.HasValue) { var personAlias = new PersonAliasService(rockContext).Get(personAliasGuid.Value); if (personAlias != null) { personAliasId = personAlias.Id; } } else { errorMessages.Add("Invalid Person Attribute or Value!"); return(false); } } // Set the connector to the connection if (!connectionRequest.ConnectorPersonAliasId.HasValue || !GetAttributeValue(action, "Ignore").AsBoolean()) { int?oldConnectorPersonAliasId = connectionRequest.ConnectorPersonAliasId; int?newConnectorPersonAliasId = personAliasId; connectionRequest.ConnectorPersonAliasId = newConnectorPersonAliasId; rockContext.SaveChanges(); if (newConnectorPersonAliasId.HasValue && !newConnectorPersonAliasId.Equals(oldConnectorPersonAliasId)) { var guid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); var assignedActivityId = new ConnectionActivityTypeService(rockContext).Queryable() .Where(t => t.Guid == guid) .Select(t => t.Id) .FirstOrDefault(); if (assignedActivityId > 0) { var connectionRequestActivityService = new ConnectionRequestActivityService(rockContext); var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId; connectionRequestActivity.ConnectorPersonAliasId = newConnectorPersonAliasId; connectionRequestActivityService.Add(connectionRequestActivity); rockContext.SaveChanges(); } } } return(true); }
/// <summary> /// Updates the trigger qualifiers. /// </summary> private void UpdateTriggerQualifiers() { RockContext rockContext = new RockContext(); String[] qualifierValues = new String[2]; ConnectionWorkflow connectionWorkflow = WorkflowsState.FirstOrDefault( l => l.Guid.Equals( hfWorkflowGuid.Value.AsGuid() ) ); ConnectionWorkflowTriggerType connectionWorkflowTriggerType = ddlTriggerType.SelectedValueAsEnum<ConnectionWorkflowTriggerType>(); int connectionTypeId = PageParameter( "ConnectionTypeId" ).AsInteger(); var connectionType = new ConnectionTypeService( rockContext ).Get( connectionTypeId ); switch ( connectionWorkflowTriggerType ) { case ConnectionWorkflowTriggerType.RequestStarted: ddlPrimaryQualifier.Visible = false; ddlPrimaryQualifier.Items.Clear(); ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; case ConnectionWorkflowTriggerType.RequestCompleted: ddlPrimaryQualifier.Visible = false; ddlPrimaryQualifier.Items.Clear(); ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; case ConnectionWorkflowTriggerType.Manual: ddlPrimaryQualifier.Visible = false; ddlPrimaryQualifier.Items.Clear(); ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; case ConnectionWorkflowTriggerType.StateChanged: ddlPrimaryQualifier.Label = "From"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.BindToEnum<ConnectionState>(); ddlPrimaryQualifier.Items.Insert( 0, new ListItem( string.Empty, string.Empty ) ); ddlSecondaryQualifier.Label = "To"; ddlSecondaryQualifier.Visible = true; ddlSecondaryQualifier.BindToEnum<ConnectionState>(); ddlSecondaryQualifier.Items.Insert( 0, new ListItem( string.Empty, string.Empty ) ); if ( !connectionType.EnableFutureFollowup ) { ddlPrimaryQualifier.Items.RemoveAt( 3 ); ddlSecondaryQualifier.Items.RemoveAt( 3 ); } break; case ConnectionWorkflowTriggerType.StatusChanged: var statusList = new ConnectionStatusService( rockContext ).Queryable().Where( s => s.ConnectionTypeId == connectionTypeId || s.ConnectionTypeId == null ).ToList(); ddlPrimaryQualifier.Label = "From"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.Items.Clear(); ddlPrimaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var status in statusList ) { ddlPrimaryQualifier.Items.Add( new ListItem( status.Name, status.Id.ToString().ToUpper() ) ); } ddlSecondaryQualifier.Label = "To"; ddlSecondaryQualifier.Visible = true; ddlSecondaryQualifier.Items.Clear(); ddlSecondaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var status in statusList ) { ddlSecondaryQualifier.Items.Add( new ListItem( status.Name, status.Id.ToString().ToUpper() ) ); } break; case ConnectionWorkflowTriggerType.ActivityAdded: var activityList = new ConnectionActivityTypeService( rockContext ).Queryable().Where( a => a.ConnectionTypeId == connectionTypeId || a.ConnectionTypeId == null ).ToList(); ddlPrimaryQualifier.Label = "Activity Type"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.Items.Clear(); ddlPrimaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var activity in activityList ) { ddlPrimaryQualifier.Items.Add( new ListItem( activity.Name, activity.Id.ToString().ToUpper() ) ); } ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; case ConnectionWorkflowTriggerType.GroupAssigned: var groupList = new GroupService( rockContext ).Queryable().ToList(); ddlPrimaryQualifier.Label = "Activity Group"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.Items.Clear(); ddlPrimaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var group in groupList ) { ddlPrimaryQualifier.Items.Add( new ListItem( group.Name, group.Id.ToString().ToUpper() ) ); } ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; } if ( connectionWorkflow != null ) { if ( connectionWorkflow.TriggerType == ddlTriggerType.SelectedValueAsEnum<ConnectionWorkflowTriggerType>() ) { qualifierValues = connectionWorkflow.QualifierValue.SplitDelimitedValues(); if ( ddlPrimaryQualifier.Visible ) { ddlPrimaryQualifier.SelectedValue = qualifierValues[0]; } if ( ddlSecondaryQualifier.Visible ) { ddlSecondaryQualifier.SelectedValue = qualifierValues[1]; } } } }
/// <summary> /// Handles the Click event of the lbConnect 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 lbConnect_Click( object sender, EventArgs e ) { using ( var rockContext = new RockContext() ) { var connectionRequestService = new ConnectionRequestService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext ); var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext ); var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() ); if ( connectionRequest != null && connectionRequest.PersonAlias != null && connectionRequest.ConnectionOpportunity != null ) { // Only do group member placement if the request has an assigned placement group if ( connectionRequest.ConnectionOpportunity.GroupMemberRoleId.HasValue && connectionRequest.AssignedGroupId.HasValue ) { // Only attempt the add if person does not already exist in group with same role var groupMember = groupMemberService.GetByGroupIdAndPersonIdAndGroupRoleId( connectionRequest.AssignedGroupId.Value, connectionRequest.PersonAlias.PersonId, connectionRequest.ConnectionOpportunity.GroupMemberRoleId.Value ); if ( groupMember == null ) { groupMember = new GroupMember(); groupMember.PersonId = connectionRequest.PersonAlias.PersonId; groupMember.GroupRoleId = connectionRequest.ConnectionOpportunity.GroupMemberRoleId.Value; groupMember.GroupMemberStatus = connectionRequest.ConnectionOpportunity.GroupMemberStatus; groupMember.GroupId = connectionRequest.AssignedGroupId.Value; groupMemberService.Add( groupMember ); } } // ... but always record the connection activity and change the state to connected. var guid = Rock.SystemGuid.ConnectionActivityType.CONNECTED.AsGuid(); var connectedActivityId = connectionActivityTypeService.Queryable() .Where( t => t.Guid == guid ) .Select( t => t.Id ) .FirstOrDefault(); if ( connectedActivityId > 0 ) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = connectedActivityId; connectionRequestActivity.ConnectorPersonAliasId = CurrentPersonAliasId; connectionRequestActivityService.Add( connectionRequestActivity ); } connectionRequest.ConnectionState = ConnectionState.Connected; rockContext.SaveChanges(); ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId ); } } }
/// <summary> /// Adds connection request(s) for the specified connectorPerson /// </summary> /// <param name="selectedCampaignItem">The selected campaign item.</param> /// <param name="connectorPerson">The connector person.</param> /// <param name="numberOfRequests">The number of requests.</param> /// <param name="numberOfRequestsRemaining">The number of requests remaining.</param> public static void AddConnectionRequestsForPerson(CampaignItem selectedCampaignItem, Person connectorPerson, int numberOfRequests, out int numberOfRequestsRemaining) { var rockContext = new RockContext(); numberOfRequestsRemaining = numberOfRequests; /* To assign requests, do the following in this order * - a) Get current connectionRequest records that don't have a connector and have a connection state of Active or a pastdue FutureFollowUp. * - b) If that runs out, get persons from the EntitySet of the selectedCampaignConnectionItem * - If there aren't enough from 'a' or 'b' */ IQueryable <ConnectionRequest> connectionRequestsWithoutConnectorQuery = GetConnectionRequestsWithoutConnectorQuery(rockContext, selectedCampaignItem, connectorPerson); numberOfRequestsRemaining = numberOfRequests; var connectionRequestsWithoutConnectorList = connectionRequestsWithoutConnectorQuery .OrderBy(a => a.CreatedDateTime) .ToList(); int connectorPersonAliasId = connectorPerson.PrimaryAliasId.Value; var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid); var connectionRequestActivityService = new ConnectionRequestActivityService(rockContext); foreach (var connectionRequest in connectionRequestsWithoutConnectorList) { connectionRequest.ConnectorPersonAliasId = connectorPersonAliasId; if (selectedCampaignItem.RequestCommentsLavaTemplate.IsNotNullOrWhiteSpace() && connectionRequest.Comments.IsNullOrWhiteSpace()) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", connectionRequest.PersonAlias.Person); mergeFields.Add("Family", connectionRequest.PersonAlias.Person.GetFamily()); connectionRequest.Comments = selectedCampaignItem.RequestCommentsLavaTemplate.ResolveMergeFields(mergeFields); } /* * 4/1/2020 - NA * * You cannot attached the connectorPerson.PrimaryAlias to the connectionRequest.ConnectorPersonAlias * because they are tracked by two different contexts. Therefore this will not work: * connectionRequest.ConnectorPersonAlias = connectorPerson.PrimaryAlias; */ if (assignedActivityId.HasValue) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequestId = connectionRequest.Id; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value; connectionRequestActivity.ConnectorPersonAliasId = connectorPersonAliasId; connectionRequestActivityService.Add(connectionRequestActivity); } numberOfRequestsRemaining--; if (numberOfRequestsRemaining <= 0) { break; } } rockContext.SaveChanges(); if (numberOfRequestsRemaining == 0) { // we were able to assign enough from connectionRequestsWithoutConnectorList, so save those changes and return return; } lock ( addConnectionRequestsLockObject ) { AssignConnectionRequestsFromEntitySet(rockContext, selectedCampaignItem, ref numberOfRequestsRemaining, connectorPerson); rockContext.SaveChanges(); } }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages ) { errorMessages = new List<string>(); var mergeFields = GetMergeFields( action ); // Get the connection request ConnectionRequest request = null; Guid connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue( action, "ConnectionRequestAttribute" ).AsGuid()).AsGuid(); request = new ConnectionRequestService( rockContext ).Get( connectionRequestGuid ); if ( request == null ) { errorMessages.Add( "Invalid Connection Request Attribute or Value!" ); return false; } // Get the activity type ConnectionActivityType activityType = null; Guid activityTypeGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionActivityTypeAttribute" ).AsGuid() ).AsGuid(); activityType = new ConnectionActivityTypeService( rockContext ).Get( activityTypeGuid ); if ( activityType == null ) { errorMessages.Add( "Invalid Connection Activity Type Attribute or Value!" ); return false; } // Get the note string noteValue = GetAttributeValue( action, "Note", true ); string note = string.Empty; Guid? noteGuid = noteValue.AsGuidOrNull(); if ( noteGuid.HasValue ) { var attribute = AttributeCache.Read( noteGuid.Value, rockContext ); if ( attribute != null ) { note = action.GetWorklowAttributeValue( noteGuid.Value ); } } else { note = noteValue; } // Get the connector int? personAliasId = null; Guid? personAttributeGuid = GetAttributeValue( action, "PersonAttribute" ).AsGuidOrNull(); if ( personAttributeGuid.HasValue ) { Guid? personAliasGuid = action.GetWorklowAttributeValue( personAttributeGuid.Value ).AsGuidOrNull(); if ( personAliasGuid.HasValue ) { var personAlias = new PersonAliasService( rockContext ).Get( personAliasGuid.Value ); if ( personAlias != null ) { personAliasId = personAlias.Id; } } } // Add the activity var activity = new ConnectionRequestActivity(); activity.ConnectionRequestId = request.Id; activity.ConnectionActivityTypeId = activityType.Id; activity.ConnectionOpportunityId = request.ConnectionOpportunityId; activity.ConnectorPersonAliasId = personAliasId; activity.Note = note.ResolveMergeFields( mergeFields ); new ConnectionRequestActivityService( rockContext ).Add( activity ); rockContext.SaveChanges(); return true; }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); var mergeFields = GetMergeFields(action); // Get the connection request ConnectionRequest request = null; Guid connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid(); request = new ConnectionRequestService(rockContext).Get(connectionRequestGuid); if (request == null) { errorMessages.Add("Invalid Connection Request Attribute or Value!"); return(false); } // Get the activity type ConnectionActivityType activityType = null; Guid activityTypeGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionActivityTypeAttribute").AsGuid()).AsGuid(); activityType = new ConnectionActivityTypeService(rockContext).Get(activityTypeGuid); if (activityType == null) { errorMessages.Add("Invalid Connection Activity Type Attribute or Value!"); return(false); } // Get the note string noteValue = GetAttributeValue(action, "Note", true); string note = string.Empty; Guid? noteGuid = noteValue.AsGuidOrNull(); if (noteGuid.HasValue) { var attribute = AttributeCache.Read(noteGuid.Value, rockContext); if (attribute != null) { note = action.GetWorklowAttributeValue(noteGuid.Value); } } else { note = noteValue; } // Get the connector int? personAliasId = null; Guid?personAttributeGuid = GetAttributeValue(action, "PersonAttribute").AsGuidOrNull(); if (personAttributeGuid.HasValue) { Guid?personAliasGuid = action.GetWorklowAttributeValue(personAttributeGuid.Value).AsGuidOrNull(); if (personAliasGuid.HasValue) { var personAlias = new PersonAliasService(rockContext).Get(personAliasGuid.Value); if (personAlias != null) { personAliasId = personAlias.Id; } } } // Add the activity var activity = new ConnectionRequestActivity(); activity.ConnectionRequestId = request.Id; activity.ConnectionActivityTypeId = activityType.Id; activity.ConnectionOpportunityId = request.ConnectionOpportunityId; activity.ConnectorPersonAliasId = personAliasId; activity.Note = note.ResolveMergeFields(mergeFields); new ConnectionRequestActivityService(rockContext).Add(activity); rockContext.SaveChanges(); return(true); }
/// <summary> /// Creates the connection requests. /// </summary> /// <param name="context">The context.</param> /// <param name="campaignItem">The campaign item.</param> /// <returns></returns> private int CreateConnectionRequests(IJobExecutionContext context, CampaignItem campaignItem) { context.UpdateLastStatusMessage($"Processing create connection requests for {campaignItem.Name}"); // Skip creating connection requests if set to "AsNeeded" and DailyLimitAssigned is 0 or null if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded && (campaignItem.DailyLimitAssigned <= 0 || campaignItem.DailyLimitAssigned == null)) { return(0); } int recordsProcessed = 0; var rockContext = new RockContext(); var connectionOpportunityService = new ConnectionOpportunityService(rockContext); var personAliasService = new PersonAliasService(rockContext); var connectionRequestService = new ConnectionRequestService(rockContext); var connectionOpportunity = connectionOpportunityService.Get(campaignItem.OpportunityGuid); if (connectionOpportunity == null) { return(0); } // get cutoff for the last connection datetime. var lastConnectionDateTime = RockDateTime.Now.AddDays(-campaignItem.DaysBetweenConnection); // if DaysBetweenConnection is 0 then check for connection request for any time period. if (campaignItem.DaysBetweenConnection == default(int)) { lastConnectionDateTime = DateTime.MinValue; } var entitySetItemService = new EntitySetItemService(rockContext); var entitySetItemsQry = entitySetItemService .Queryable() .Where(a => a.EntitySetId == campaignItem.EntitySetId) .OrderBy(a => a.Order); bool autoAssignment = false; var eligibleConnectors = new List <ConnectionConnector>(); if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded && campaignItem.DailyLimitAssigned.HasValue && campaignItem.DailyLimitAssigned != default(int)) { autoAssignment = true; eligibleConnectors = GetEligibleConnectorWithLimit(connectionOpportunity.Id, rockContext, campaignItem.DailyLimitAssigned.Value); } int?connectionStatusId = connectionOpportunity.ConnectionType.ConnectionStatuses .Where(s => s.IsDefault) .Select(s => ( int? )s.Id) .FirstOrDefault(); // If opportunity doesn't have a default status, something is wrong if (connectionStatusId == null) { ExceptionLogService.LogException(new Exception($"Unable to determine default connection status for {connectionOpportunity.Name} while processing campaigns", null)); return(0); } var dayofWeek = RockDateTime.Now.DayOfWeek; var entitySetItemList = entitySetItemsQry.ToList(); foreach (var entitySetItem in entitySetItemList) { var personAlias = personAliasService.GetPrimaryAlias(entitySetItem.EntityId); var defaultCampus = personAlias.Person.GetCampus(); int?connectorPersonAliasId = null; if (autoAssignment) { int?connectorPersonId = null; if (campaignItem.PreferPreviousConnector) { var personIds = eligibleConnectors .Where(a => a.Limit - a.Current > 0 && (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) && (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value))) .Select(a => a.PersonId) .ToList(); if (personIds.Any()) { var person = connectionRequestService .Queryable() .Where(a => a.ConnectionOpportunityId == connectionOpportunity.Id && a.PersonAlias.PersonId == personAlias.PersonId && a.ConnectionState == ConnectionState.Connected && a.ConnectorPersonAliasId.HasValue && personIds.Contains(a.ConnectorPersonAlias.PersonId)) .Select(a => a.ConnectorPersonAlias.Person) .FirstOrDefault(); if (person != null) { connectorPersonId = person.Id; } } } if (!connectorPersonId.HasValue) { var eligibleConnector = eligibleConnectors .Where(a => a.Limit - a.Current > 0 && (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) && (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value))) .OrderBy(a => a.Current) // order from least assigned to most assigned .ThenBy(x => Guid.NewGuid()) // and then randomize .FirstOrDefault(); if (eligibleConnector != null) { connectorPersonId = eligibleConnector.PersonId; } } if (!connectorPersonId.HasValue) { continue; } foreach (var connectionConnector in eligibleConnectors.Where(a => a.PersonId == connectorPersonId.Value)) { connectorPersonAliasId = connectionConnector.PersonAliasId; connectionConnector.Current += 1; } } using (var insertRockContext = new RockContext()) { try { /* * 3/30/2020 - NA * * When setting the connection request's Requester, we have to use the PrimaryAlias * to set the connectionRequest.PersonAlias property because the ConnectionRequestChangeTransaction * https://github.com/SparkabilityGroup/Rock/blob/a556a9285b7fdfe5594441286242f4feaa5847f2/Rock/Transactions/ConnectionRequestChangeTransaction.cs#L123 * (which handles triggered workflows) expects it. Also, it needs to be tracked by * the current rockContext... * * In other words, this will not work correctly: * PersonAliasId = personAlias.Id, * * Reason: This plug-in cannot change Rock core assembly code. */ var personPrimaryAlias = new PersonAliasService(insertRockContext).GetPrimaryAlias(entitySetItem.EntityId); var connectionRequestActivityService = new ConnectionRequestActivityService(insertRockContext); var insertConnectionRequestService = new ConnectionRequestService(insertRockContext); // double check that they haven't already been added var personAlreadyHasConnectionRequest = CampaignConnectionHelper.PersonAlreadyHasConnectionRequest(connectionOpportunity.Id, rockContext, lastConnectionDateTime, entitySetItem.EntityId); if (personAlreadyHasConnectionRequest) { continue; } var connectionRequest = new ConnectionRequest() { ConnectionOpportunityId = connectionOpportunity.Id, PersonAlias = personPrimaryAlias, ConnectionState = ConnectionState.Active, ConnectorPersonAliasId = connectorPersonAliasId, CampusId = defaultCampus?.Id, ConnectionStatusId = connectionStatusId.Value, }; if (campaignItem.RequestCommentsLavaTemplate.IsNotNullOrWhiteSpace()) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", personAlias.Person); mergeFields.Add("Family", personAlias.Person.GetFamily()); connectionRequest.Comments = campaignItem.RequestCommentsLavaTemplate.ResolveMergeFields(mergeFields); } insertConnectionRequestService.Add(connectionRequest); if (connectorPersonAliasId.HasValue) { var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid(); int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid); if (assignedActivityId.HasValue) { var connectionRequestActivity = new ConnectionRequestActivity(); connectionRequestActivity.ConnectionRequest = connectionRequest; connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId; connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value; connectionRequestActivity.ConnectorPersonAliasId = connectorPersonAliasId; connectionRequestActivityService.Add(connectionRequestActivity); } } insertRockContext.SaveChanges(); } catch (Exception ex) { // Log exception and keep on trucking. var exception = new Exception($"Exception occurred trying to create connection request:{personAlias.Id}.", ex); createConnectionRequestExceptions.Add(exception); ExceptionLogService.LogException(exception, null); } } recordsProcessed += 1; } return(recordsProcessed); }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls(Type entityType, FilterField filterControl) { var ddlActivityType = new RockDropDownList(); ddlActivityType.ID = filterControl.ID + "_ddlActivityType"; ddlActivityType.AddCssClass("js-activity-type"); ddlActivityType.Label = "Activity Type"; filterControl.Controls.Add(ddlActivityType); var activityTypes = new ConnectionActivityTypeService(new RockContext()).Queryable("ConnectionType").AsNoTracking().Where(a => a.IsActive) .OrderBy(a => a.ConnectionTypeId.HasValue) .ThenBy(a => a.Name) .ToList(); ddlActivityType.Items.Clear(); ddlActivityType.Items.Insert(0, new ListItem()); foreach (var activityType in activityTypes) { var activityName = GetActivityName(activityType); ddlActivityType.Items.Add(new ListItem(activityName, activityType.Guid.ToString())); } var ddlIntegerCompare = ComparisonHelper.ComparisonControl(ComparisonHelper.NumericFilterComparisonTypes); ddlIntegerCompare.Label = "Count"; ddlIntegerCompare.ID = filterControl.ID + "_ddlIntegerCompare"; ddlIntegerCompare.AddCssClass("js-filter-compare"); filterControl.Controls.Add(ddlIntegerCompare); var nbCount = new NumberBox(); nbCount.ID = filterControl.ID + "_nbCount"; nbCount.Label = " "; // give it whitespace label so it lines up nicely nbCount.AddCssClass("js-count"); filterControl.Controls.Add(nbCount); var slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.Label = "Date Range"; slidingDateRangePicker.ID = filterControl.ID + "_slidingDateRangePicker"; slidingDateRangePicker.AddCssClass("js-sliding-date-range"); filterControl.Controls.Add(slidingDateRangePicker); var controls = new Control[4] { ddlActivityType, ddlIntegerCompare, nbCount, slidingDateRangePicker }; // convert pipe to comma delimited var defaultDelimitedValues = slidingDateRangePicker.DelimitedValues.Replace("|", ","); var defaultCount = 1; // set the default values in case this is a newly added filter var selectionConfig = new SelectionConfig() { IntegerCompare = ComparisonType.GreaterThanOrEqualTo, MinimumCount = defaultCount, SlidingDateRangeDelimitedValues = defaultDelimitedValues }; SetSelection( entityType, controls, selectionConfig.ToJson()); return(controls); }
/// <summary> /// Updates the trigger qualifiers. /// </summary> private void UpdateTriggerQualifiers() { using ( var rockContext = new RockContext() ) { String[] qualifierValues = new String[2]; ConnectionWorkflow connectionWorkflow = WorkflowsState.FirstOrDefault( l => l.Guid.Equals( hfAddConnectionWorkflowGuid.Value.AsGuid() ) ); ConnectionWorkflowTriggerType connectionWorkflowTriggerType = ddlTriggerType.SelectedValueAsEnum<ConnectionWorkflowTriggerType>(); int connectionTypeId = int.Parse( hfConnectionTypeId.Value ); switch ( connectionWorkflowTriggerType ) { case ConnectionWorkflowTriggerType.RequestStarted: case ConnectionWorkflowTriggerType.RequestAssigned: case ConnectionWorkflowTriggerType.RequestTransferred: case ConnectionWorkflowTriggerType.RequestConnected: case ConnectionWorkflowTriggerType.PlacementGroupAssigned: case ConnectionWorkflowTriggerType.Manual: { ddlPrimaryQualifier.Visible = false; ddlPrimaryQualifier.Items.Clear(); ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; } case ConnectionWorkflowTriggerType.StateChanged: { ddlPrimaryQualifier.Label = "From"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.BindToEnum<ConnectionState>(); ddlPrimaryQualifier.Items.Insert( 0, new ListItem( string.Empty, string.Empty ) ); ddlSecondaryQualifier.Label = "To"; ddlSecondaryQualifier.Visible = true; ddlSecondaryQualifier.BindToEnum<ConnectionState>(); ddlSecondaryQualifier.Items.Insert( 0, new ListItem( string.Empty, string.Empty ) ); if ( !cbFutureFollowUp.Checked ) { ddlPrimaryQualifier.Items.RemoveAt( 3 ); ddlSecondaryQualifier.Items.RemoveAt( 3 ); } break; } case ConnectionWorkflowTriggerType.StatusChanged: { var statusList = new ConnectionStatusService( rockContext ).Queryable().Where( s => s.ConnectionTypeId == connectionTypeId || s.ConnectionTypeId == null ).ToList(); ddlPrimaryQualifier.Label = "From"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.Items.Clear(); ddlPrimaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var status in statusList ) { ddlPrimaryQualifier.Items.Add( new ListItem( status.Name, status.Id.ToString().ToUpper() ) ); } ddlSecondaryQualifier.Label = "To"; ddlSecondaryQualifier.Visible = true; ddlSecondaryQualifier.Items.Clear(); ddlSecondaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var status in statusList ) { ddlSecondaryQualifier.Items.Add( new ListItem( status.Name, status.Id.ToString().ToUpper() ) ); } break; } case ConnectionWorkflowTriggerType.ActivityAdded: { var activityList = new ConnectionActivityTypeService( rockContext ) .Queryable().AsNoTracking() .Where( a => a.ConnectionTypeId == connectionTypeId ) .ToList(); ddlPrimaryQualifier.Label = "Activity Type"; ddlPrimaryQualifier.Visible = true; ddlPrimaryQualifier.Items.Clear(); ddlPrimaryQualifier.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( var activity in activityList ) { ddlPrimaryQualifier.Items.Add( new ListItem( activity.Name, activity.Id.ToString().ToUpper() ) ); } ddlSecondaryQualifier.Visible = false; ddlSecondaryQualifier.Items.Clear(); break; } } if ( connectionWorkflow != null ) { if ( connectionWorkflow.TriggerType == ddlTriggerType.SelectedValueAsEnum<ConnectionWorkflowTriggerType>() ) { qualifierValues = connectionWorkflow.QualifierValue.SplitDelimitedValues(); if ( ddlPrimaryQualifier.Visible && qualifierValues.Length > 0 ) { ddlPrimaryQualifier.SelectedValue = qualifierValues[0]; } if ( ddlSecondaryQualifier.Visible && qualifierValues.Length > 1 ) { ddlSecondaryQualifier.SelectedValue = qualifierValues[1]; } } } } }