workflow-core
workflow-core copied to clipboard
Workflow step requires approval; rejection starts the workflow over
Hello, Daniel,
In Issue #330 you said you could provide an example of a workflow with approval/rejection given more detail. Could you please provide an idea for the following?
The workflow prompts a user to fill out some data for a project. The workflow waits for the manager's approval and retrieves the answer via an event. The workflow then provides a branching structure based on the manager's response. If the manager has approved the work the workflow follows one branch forward to the next workflow step. If the manager has rejected the work, the workflow starts over at the prior step prompting the user to correct the data and resubmit it for approval.
How can I accomplish this? Thanks in advance!
This is my attempt:
public void Build(IWorkflowBuilder<YesNoData> builder)
{
var userNotificationProcess = builder
.StartWith(context => ExecutionResult.Next())
.Then<NotifyUser>()
.Input(step => step.UserName, data => "[email protected]");
var approvalBranch = builder.CreateBranch()
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "The plan is approved")
.Then<PrintMessage>()
.Input(step => step.Message, data => "Moving to next step")
.Then<NotifyUser>()
.Input(step => step.UserName, data => "[email protected]");
var rejectionBranch = builder.CreateBranch()
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "The plan is rejected")
.Then<PrintMessage>()
.Input(step => step.Message, data => "Starting plan over")
.Then(userNotificationProcess);
userNotificationProcess
.WaitFor("Approval_Decision", (data, context) => context.Workflow.Id, date => DateTime.Now.ToUniversalTime())
.Output(data => data.Value, step => step.EventData)
.Decide(data => data.Value)
.Branch("yes", approvalBranch)
.Branch("no", rejectionBranch);
}
I was able to do this with a While loop as follows, but if you can think of a more elegant solution please let me know. One issue with this approach is that it creates duplicate ExecutionPointers for the steps in the While loop as well as for all the steps following the While loop.
var userNotificationProcess = builder
.Then<NotifyUserDataEntry>()
.Input(step => step.UserName, data => "[email protected]");
var rejectionNotificationProcess = builder
.Then<PrintMessage>()
.Input(step => step.Message, data => "The plan is rejected")
.Then<PrintMessage>()
.Input(step => step.Message, data => "Starting plan over")
.Then<NotifyUserRejection>()
.Input(step => step.UserName, data => "[email protected]");
var approvalDecisionProcess = builder
.WaitFor("Approval_Decision", (data, context) => context.Workflow.Id, date => DateTime.Now.ToUniversalTime())
.Output(data => data.Status, step => step.EventData);
builder
.StartWith(context => ExecutionResult.Next())
.Then(userNotificationProcess)
.Then(approvalDecisionProcess)
.While(data => data.Status == "rejected")
.Do(x => x
.Then(rejectionNotificationProcess)
.Then(approvalDecisionProcess)
)
.Then<PrintMessage>()
.Input(step => step.Message, data => "The plan is approved")
.Then<PrintMessage>()
.Input(step => step.Message, data => "Moving to next step");