Importing a non-CRM Workflow 

On a recent project, one of our senior CRM development team members had the challenge of importing Opportunities that were in the middle of a workflow.  Here is a post Chris Scott worked up on the subject:

Recently I worked on a data migration project from a legacy system to Microsoft CRM. As part of this migration, opportunities were migrated including a field that was essentially equivalent to a workflow stage. The customer wanted to use the CRM workflow and update each opportunities workflow stage to the legacy system’s equivalent.  The customer’s preference was to set the stage of the workflow without any of the previous workflow tasks being created. If this was not supported, then their next preference was to set each of the tasks as cancelled until the appropriate stage in the workflow was reached.


Workflow details
The workflow process had 9 stages with 3 to 5 tasks in each stage. Once a specific set of tasks (one or more) were marked as completed, the next stage would open up with its associate tasks. The workflow would fire upon creation of a customer record creating a sales process task list and setting the CloseProbability in the Opportunity entity to a predetermined value.


Design overview
Our investigations revealed that the customer’s first preference of skipping ahead to the appropriate stage level without creating the children tasks was not supported. We found that the method CurrentStepId within the WFProcessInstance class would set the stage to a specific level, but when we attempted to set the CurrentStepID to a future stage an error was generated. We found that this error was caused by the supporting workflow database records associated with each tasks are not created until the previous stage is completed / cancelled / skipped. What this meant is we would have to go and, using the imported data, programmatically set each task within already completed task to “cancelled”. To accomplish this, we used the SetStateTaskRequest to set each TaskState and TaskStatus until the appropriate stage was reached. As each task status was changed, CRM would create the associated database records and open the next stage.


Code overview
We created a C# console application that retrieves records from a custom stored procedure. The stored procedure queries the FilteredActivityPointer table where the TypeCodeName is a task and the opportunity is active.
Note: Custom stored procedures are not supported within CRM.  For this purpose however, the stored procedure was only used during the initial data migration and dropped after the migration was completed.


The stored procedure only retrieve records where the current workflow CloseProbability (stored in FilteredOpportunity) is less than the legacy CloseProbability value (code not shown).


The console app created a loop calling the stored procedure until the no records were returned.  For each procedure call, the console looped through the records setting the TaskState and TaskStatus to “cancelled” for a specific ActivityID for an EntityId:

CrmService crmService = CrmUtility.GetCrmService();

  //Set the values to canceled for the state & status

SetStateTaskRequest stateTask = new SetStateTaskRequest();

stateTask.TaskState = TaskState.Canceled;

stateTask.TaskStatus = 6;

  //Open the database connection

oSQLConn.Open();

SqlDataReader dr = cmd.ExecuteReader();

while(dr.Read())

{

//Set the EntityId to the ActivityId

stateTask.EntityId = dr.GetGuid(0

//Set the state of each task to cancelled

crmService.Execute(stateTask);

}

oSQLConn.Close();

Lessons learned
During the import of opportunities records (prior to updating the workflow tasks), we found that with the workflow enabled, the Opportunity CloseProbability value was overridden resetting each value to 0. Although this was unexpected, it is the "by design" of the workflow process.  However, this meant in order to maintain legacy information, we needed to store the legacy CloseProbability value into a custom column.

We also found that once a workflow is enabled and associated with an opportunity, an instance of the workflow is created for that opportunity. This instance is independent of the “main” workflow and will run its course until completed or cancelled even if the “main” workflow is altered or deactivated. Each instance and its detailed can be viewed in the workflow monitor (under the Microsoft CRM start menu group).  This tool, often overlooked, can be your biggest ally when trying to understand what is happening within a workflow.

This posting is provided "AS IS" with no warranties, and confers no rights.

Comments
No Comments Available
Add a New Comment
Name

Email Address

Url

Comment