/// <summary> /// Invokes an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext" /> to associate with this activity and execution.</param> /// <returns> /// The <see cref="ActionActivityResult" /> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> private async Task <ActionActivityResult> ExecuteNodeAsync(ActionActivityContext context, CancellationToken cancellationToken) { Debug.Assert(context != null); if (context.Action.Type == ActionType.Log) { context.HasLogAction = true; } if (!context.Action.Enabled) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var descriptor = FindActionDescriptor(context.Action.Type); if (descriptor == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var status = await descriptor.Activity.ExecuteAsync(context, cancellationToken); if (status.StatusCode == ActionActivityStatusCode.Success && context.Action.Children.Count > 0) { status = await ExecuteNodeListAsync(context, context.Action.Children.OfType <ActionItem>(), cancellationToken); } return(status); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { if (context.Contact == null || context.ContactState == ObjectState.Deleted) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } ValidationResult validationResult; var projectManager = context.Resolve <ProjectManager>(); if (context.ContactExists) { validationResult = await projectManager.ReplaceContactAsync(context.Project, context.Contact, context.Contact, cancellationToken); if (validationResult.Succeeded) { context.ContactState = ObjectState.Modified; } } else { validationResult = await projectManager.AddContactAsync(context.Project, context.Contact, cancellationToken); if (validationResult.Succeeded) { context.ContactState = ObjectState.Added; } } return(context.CreateResult(validationResult.Succeeded ? ActionActivityStatusCode.Success : ActionActivityStatusCode.Failed)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { if (!context.ContactExists || context.ContactState == ObjectState.Deleted) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Failed))); } var options = context.Action.Options?.ToObject <Options>(); if (options == null) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Failed))); } // Schedule this action with its children using the given time values BackgroundJob.Schedule <ScheduleActionJob>(job => job.Execute(new ScheduleActionJobData { ActionId = context.Action.Id, AuthTicket = context.AuthTicket, AnonymId = context.AnonymId, Contact = context.Contact, ContactState = context.ContactState, Properties = context.Properties, Event = context.Event }), new DateTimeOffset(options.StartDate).Add(options.OffsetTime)); // Break control flow to avoid to execute children actions return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Failed))); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var projectManager = context.Resolve <ProjectManager>(); if (!context.ContactExists || context.ContactState == ObjectState.Deleted) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var validationResult = await projectManager.RemoveContactAsync(context.Project, context.Contact, cancellationToken); if (validationResult.Succeeded) { context.ContactState = ObjectState.Deleted; return(context.CreateResult(ActionActivityStatusCode.Success)); } return(context.CreateResult(ActionActivityStatusCode.Failed)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { if (!context.ContactExists) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Forbidden))); } if (context.ContactState == ObjectState.Deleted) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Failed))); } if ((context.AuthTicket == null) || (context.Contact.Id != context.AuthTicket.Id)) { context.AnonymId = GuidUtility.NewSequentialGuid(); } context.AuthTicket = AuthUtility.Create(context.Contact); return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Success))); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var projectManager = context.Resolve <ProjectManager>(); var mailService = context.Resolve <IMailClientService>(); if (!context.ContactExists || context.ContactState == ObjectState.Deleted) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var options = context.Action.Options?.ToObject <Options>(); if (options == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var message = await projectManager.GetMailMessageByIdAsync(options.Id, MailMessageField.Body, cancellationToken); if (message == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var project = await projectManager.FindByIdAsync(context.Project.Id, cancellationToken); if (project == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var header = new MailMessageHeader(); header.To.Add(context.Contact.Id); var invitation = context.Properties["Invitation"] as ProjectInvitation; if (invitation != null) { header.From = invitation.From; header.Placeholders[ActionResources.Invitation] = invitation; } await mailService.SendAsync(project, header, message, cancellationToken); return(context.CreateResult(ActionActivityStatusCode.Success)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var result = context.CreateResult(ActionActivityStatusCode.Failed); var options = context.Action.Options?.ToObject <Options>(); if (options != null) { result.StatusCode = ActionActivityStatusCode.Success; result.ReturnUrl = GenerateUrl(context, options); //result.ReturnUrl = IsValidLocalUrl(context, options.Url) ? GenerateUrl(context, options) : options.Url; } return(Task.FromResult(result)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var projectManager = context.Resolve <ProjectManager>(); if (!context.ContactExists || context.ContactState == ObjectState.Deleted) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } var options = context.Action.Options?.ToObject <Options>(); if (options == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } await projectManager.SetBusinessTagsAsync( new[] { context.Contact.Id }, options.Include ?? Enumerable.Empty <int>(), options.Exclude ?? Enumerable.Empty <int>(), cancellationToken); context.ContactState = ObjectState.Modified; return(context.CreateResult(ActionActivityStatusCode.Success)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var projectManager = context.Resolve <ProjectManager>(); var logManager = context.Resolve <LogManager>(); var options = context.Action.Options?.ToObject <Options>(); if (options == null || (!options.Anonymous && !context.ContactExists)) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } if (context.ContactExists) { context.Event.Contact = context.Contact; context.Event.ContactState = context.ContactState; } else { context.Event.Contact = null; context.Event.ContactState = ObjectState.Unchanged; } await logManager.LogAsync(context.Event, context.Project.Owners, cancellationToken); return(context.CreateResult(ActionActivityStatusCode.Success)); }
/// <summary> /// Invokes an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext" /> to associate with this activity and execution.</param> /// <param name="actions">The actions.</param> /// <returns> /// The <see cref="ActionActivityResult" /> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> private async Task <ActionActivityResult> ExecuteNodeListAsync(ActionActivityContext context, IEnumerable <ActionItem> actions, CancellationToken cancellationToken) { Debug.Assert(context != null); Debug.Assert(actions != null); ActionActivityResult status = null; foreach (var action in actions) { context = context.Clone(action); status = await ExecuteNodeAsync(context, cancellationToken); if (status.StatusCode == ActionActivityStatusCode.Success && status.ReturnUrl != null || status.StatusCode == ActionActivityStatusCode.Forbidden) { return(status); } } return(status ?? context.CreateResult(ActionActivityStatusCode.Failed)); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Success))); }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public async Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { var options = context.Action.Options?.ToObject <Options>(); if (options == null || options.Conditions == null) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } bool succeeded = true; var includeWithTagIds = new HashSet <int>(); var excludeWithTagIds = new HashSet <int>(); foreach (var condition in options.Conditions) { switch (condition?.Type) { case ConditionType.DateGreaterThanOrEqualTo: { DateTime value; succeeded &= DateTime.TryParse(condition.Value, out value) ? (DateTime.UtcNow >= value) : false; } break; case ConditionType.DateLessThanOrEqualTo: { DateTime value; succeeded &= DateTime.TryParse(condition.Value, out value) ? (DateTime.UtcNow <= value) : false; } break; case ConditionType.Authenticated: { bool value; succeeded &= bool.TryParse(condition.Value, out value) ? context.IsAuthenticated == value : false; } break; case ConditionType.ContactExists: { bool value; succeeded &= bool.TryParse(condition.Value, out value) ? context.ContactExists == value : false; } break; case ConditionType.ContactWithTag: { int value; if (succeeded &= int.TryParse(condition.Value, out value)) { includeWithTagIds.Add(value); } } break; case ConditionType.ContactWithoutTag: { int value; if (succeeded &= int.TryParse(condition.Value, out value)) { excludeWithTagIds.Add(value); } } break; default: succeeded = false; break; } if (!succeeded) { return(context.CreateResult(ActionActivityStatusCode.Failed)); } } if (context.ContactExists && context.ContactState != ObjectState.Deleted && (includeWithTagIds.Count | excludeWithTagIds.Count) > 0) { var projectManager = context.Resolve <ProjectManager>(); succeeded &= await projectManager.HasBusinessTagsAsync( context.Contact, includeWithTagIds, excludeWithTagIds, cancellationToken); } return(context.CreateResult(succeeded ? ActionActivityStatusCode.Success : ActionActivityStatusCode.Failed)); }