[Code Snippet] Set Business process flow (BPF) stage using C#
Assume you have a BPF with 3 Stages on an Entity ‘Employer’. When you create a new ‘Employer’ record, by default ‘Stage-1’ gets set.
What if you have to create the ‘Employer’ record with a different stage.
Lets see how to create a record and set the desired BPF stage with an example entity ‘Employer’.
I’ve an ‘Employer’ entity and a BPF name ‘Employer flow’ with 3 stages named ‘Basic Details’, ‘Address’ and ‘Experience’.

Key point to notice is, when ever you create a BPF a new entity gets created with the given BPF name.

Following are the steps to create a ‘Employer’ record and set the BPF stage to ‘Experience’.
- Query ‘Workflow’ entity to get the ‘BPF ID’ by passing the BPF entity schema name (i.e., crf10_employerflow).
var queryEmployerBPF = new QueryExpression
{
EntityName = "workflow",
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "uniquename",
Operator = ConditionOperator.Equal,
Values = { "crf10_employerflow" }
}
}
}
};
var retrievedBPF = ConnectionManager.CrmService.RetrieveMultiple(queryEmployerBPF).Entities[0];
var _bpfId = retrievedBPF.Id;
- Query Process Stage by passing ‘BPF ID’ fetched in previous step.
var queryPS = new QueryExpression{
EntityName = "processstage",
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression{
Conditions ={
new ConditionExpression{
AttributeName = "processid",
Operator = ConditionOperator.Equal,
Values={ _bpfId }
}
}
}
};
- Copy the ‘Stage’ GUID’s which will be used in next steps.
- Create the ‘Employer’ record, which also creates record in ‘BPF entity’ (i.e., Employer Flow).
Entity entEmployer = new Entity("crf10_employer");
entEmployer["crf10_name"] = "BPF Test";
//entEmployer["processid"] = Guid.Empty;
var violationID = ConnectionManager.CrmService.Create(entEmployer);
- Fetch the ‘BPF entity’ (i.e., Employer Flow) record, which auto created in previous step, using ‘RetrieveProcessInstancesRequest’ request.
var procOpp2Req = new RetrieveProcessInstancesRequest
{
EntityId = violationID,
EntityLogicalName = "crf10_employer"
};
var procOpp2Resp = (RetrieveProcessInstancesResponse)ConnectionManager.CrmService.Execute(procOpp2Req);
- Update ‘activestageid’ field of the ‘BPF entity’ (i.e., Employer Flow) record fetched in previous step, with the desired stage GUID captured in Step #2.

// Declare variables to store values returned in response
int processCount = procOpp2Resp.Processes.Entities.Count;
var activeProcessInstance = procOpp2Resp.Processes.Entities[0]; // First record is the active process instance
var _processOpp2Id = activeProcessInstance.Id; // Id of the active process instance, which will be used
// Retrieve the process instance record to update its active stage
ColumnSet cols1 = new ColumnSet();
cols1.AddColumn("activestageid");
Entity retrievedProcessInstance = ConnectionManager.CrmService.Retrieve("crf10_employerflow", _processOpp2Id, cols1);
// Update the stage to 'Experience' by passing GUID (i.e.,"05aeaf03-e135-40ac-8ae7-cafc7d746a02")
retrievedProcessInstance["activestageid"] = new EntityReference("processstage", new Guid("05aeaf03-e135-40ac-8ae7-cafc7d746a02"));
ConnectionManager.CrmService.Update(retrievedProcessInstance);
- Open the record from the App and the stage should set to ‘Experience’.

- Check the BPF records and you should see ‘Active Stage’ got set to ‘Experience’ (This is optional step and for your learning).

- Below is the complete snippet.
var queryEmployerBPF = new QueryExpression
{
EntityName = "workflow",
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "uniquename",
Operator = ConditionOperator.Equal,
Values = { "crf10_employerflow" }
}
}
}
};
var retrievedBPF = ConnectionManager.CrmService.RetrieveMultiple(queryEmployerBPF).Entities[0];
var _bpfId = retrievedBPF.Id;
var queryPS = new QueryExpression
{
EntityName = "processstage",
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "processid",
Operator = ConditionOperator.Equal,
Values={ _bpfId }
}
}
}
};
var retrievedPS = ConnectionManager.CrmService.RetrieveMultiple(queryPS);
// Copy the Stage GUID's using below loop.
foreach (var stage in retrievedPS.Entities)
{
Console.WriteLine($"Stage Name : {stage["stagename"]}");
Console.WriteLine($"Stage ID : {stage["processstageid"]}");
}
//Create 'Employer' record
var entEmployer = new Entity("crf10_employer");
entEmployer["crf10_name"] = "BPF Test";
//entEmployer["processid"] = Guid.Empty;
var violationID = ConnectionManager.CrmService.Create(entEmployer);
var procOpp2Req = new RetrieveProcessInstancesRequest
{
EntityId = violationID,
EntityLogicalName = "crf10_employer"
};
var procOpp2Resp = (RetrieveProcessInstancesResponse)ConnectionManager.CrmService.Execute(procOpp2Req);
// Declare variables to store values returned in response
int processCount = procOpp2Resp.Processes.Entities.Count;
var activeProcessInstance = procOpp2Resp.Processes.Entities[0]; // First record is the active process instance
var _processOpp2Id = activeProcessInstance.Id; // Id of the active process instance, which will be used
// Retrieve the process instance record to update its active stage
var cols1 = new ColumnSet();
cols1.AddColumn("activestageid");
var retrievedProcessInstance = ConnectionManager.CrmService.Retrieve("crf10_employerflow", _processOpp2Id, cols1);
// Update the stage to 'Experience' by passing GUID (i.e.,"05aeaf03-e135-40ac-8ae7-cafc7d746a02")
retrievedProcessInstance["activestageid"] = new EntityReference("processstage", new Guid("05aeaf03-e135-40ac-8ae7-cafc7d746a02"));
ConnectionManager.CrmService.Update(retrievedProcessInstance);
🙂
Could you please let us know on which step do i need to register this step
This is apt for migration scenario. Code needs to be triggered from C# Console.