Ejemplo n.º 1
0
        /// <summary>
        /// Creates any entity records that this sample requires.
        /// </summary>
        public void CreateRequiredRecords()
        {
            // Create a sample Lead record.
            // This will also create an instance of "Lead To Opportunity Sales Process"
            // BPF for the new lead record.
            Lead myLead = new Lead
            {
                Subject   = "SDK Sample Record",
                FirstName = "Randy",
                LastName  = "Blythe"
            };

            _leadId = _serviceProxy.Create(myLead);
            Console.WriteLine("\nCreated a Lead: '{0}'.", myLead.Subject);


            // Verify that an instance of "Lead To Opportunity Sales Process" is created for the new Lead record.
            RetrieveProcessInstancesRequest procLeadReq = new RetrieveProcessInstancesRequest
            {
                EntityId          = _leadId,
                EntityLogicalName = Lead.EntityLogicalName
            };
            RetrieveProcessInstancesResponse procLeadResp = (RetrieveProcessInstancesResponse)_serviceProxy.Execute(procLeadReq);

            if (procLeadResp.Processes.Entities.Count > 0)
            {
                var processLeadInstance = procLeadResp.Processes.Entities[0];
                Console.WriteLine("Process instance automatically created for the new Lead record: '{0}'", processLeadInstance["name"]);
            }
            else
            {
                Console.WriteLine("No processes found for the Lead record; aborting the sample.");
                Environment.Exit(1);
            }
        }
        protected override void ExecuteInternal(LocalWorkflowContext context)
        {
            var stageNameToSet = this.StageNameInArgument.Get(context.CodeActivityContext).ToUpper();

            RetrieveProcessInstancesRequest retrieveProcessInstancesRequest = new RetrieveProcessInstancesRequest
            {
                EntityId          = context.WorkflowContext.PrimaryEntityId,
                EntityLogicalName = context.WorkflowContext.PrimaryEntityName
            };

            RetrieveProcessInstancesResponse retrievedProcessInstancesResponse = (RetrieveProcessInstancesResponse)context.OrganizationService.Execute(retrieveProcessInstancesRequest);

            var     activeProcessInstance = retrievedProcessInstancesResponse.Processes.Entities[0]; // First record is the active process instance
            var     workflowReference     = (EntityReference)activeProcessInstance.Attributes["processid"];
            Process workflow = context.OrganizationService.Retrieve(workflowReference.LogicalName, workflowReference.Id, new ColumnSet(true)).ToEntity <Process>();

            RetrieveActivePathRequest pathRequest = new RetrieveActivePathRequest
            {
                ProcessInstanceId = activeProcessInstance.Id
            };

            RetrieveActivePathResponse pathResponse = (RetrieveActivePathResponse)context.OrganizationService.Execute(pathRequest);
            var stageToSetId = (Guid)pathResponse.ProcessStages.Entities.Where(x => x.Attributes["stagename"].ToString().ToUpper() == stageNameToSet).First().Attributes["processstageid"];

            ColumnSet columns = new ColumnSet();

            columns.AddColumn("activestageid");
            Entity retrievedProcessInstance = context.OrganizationService.Retrieve(workflow.UniqueName, activeProcessInstance.Id, columns);

            // Set the next stage as the active stage
            retrievedProcessInstance["activestageid"] = new EntityReference(ProcessStage.EntityLogicalName, stageToSetId);
            context.OrganizationService.Update(retrievedProcessInstance);
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            IOrganizationService organizationService = null;

            try
            {
                ClientCredentials clientCredentials = new ClientCredentials();
                clientCredentials.UserName.UserName = "******";
                clientCredentials.UserName.Password = "******";

                // For Dynamics 365 Customer Engagement V9.X, set Security Protocol as TLS12
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                // Get the URL from CRM, Navigate to Settings -> Customizations -> Developer Resources
                // Copy and Paste Organization Service Endpoint Address URL
                organizationService = (IOrganizationService) new OrganizationServiceProxy(new Uri("https://hsodevelopment2.api.crm3.dynamics.com/XRMServices/2011/Organization.svc"),
                                                                                          null, clientCredentials, null);

                if (organizationService != null)
                {
                    Guid userid = ((WhoAmIResponse)organizationService.Execute(new WhoAmIRequest())).UserId;

                    if (userid != Guid.Empty)
                    {
                        Console.WriteLine("Connection Established Successfully...");
                    }

                    Entity TargetEntity = organizationService.Retrieve("opportunity", Guid.Parse("B76E3BEC-429B-E811-80C2-00155D011409"), new Microsoft.Xrm.Sdk.Query.ColumnSet(true));

                    var activeInstancesRequest = new RetrieveProcessInstancesRequest
                    {
                        EntityId          = TargetEntity.Id,
                        EntityLogicalName = TargetEntity.LogicalName
                    };



                    Console.WriteLine(TargetEntity.GetAttributeValue <EntityReference>("stageid"));
                }
                else
                {
                    Console.WriteLine("Failed to Established Connection!!!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception caught - " + ex.Message);
            }
            Console.ReadKey();
        }
        public static Entity GetProcessInstanceOfRecord(CrmTestingContext crmContext, EntityReference crmRecord)
        {
            if (crmRecord == null)
            {
                return(null);
            }

            var request = new RetrieveProcessInstancesRequest()
            {
                EntityId          = crmRecord.Id,
                EntityLogicalName = crmRecord.LogicalName
            };
            var response = GlobalTestingContext.ConnectionManager.CurrentConnection.Execute <RetrieveProcessInstancesResponse>(request);

            return(response.Processes.Entities.FirstOrDefault());
        }
Ejemplo n.º 5
0
        public static void ChangeStage(IOrganizationService service, Guid op)
        {
            // Get Process Instances
            RetrieveProcessInstancesRequest processInstanceRequest = new RetrieveProcessInstancesRequest
            {
                EntityId          = op,
                EntityLogicalName = Opportunity.EntityLogicalName
            };

            RetrieveProcessInstancesResponse processInstanceResponse = (RetrieveProcessInstancesResponse)service.Execute(processInstanceRequest);

            // Declare variables to store values returned in response
            int    processCount            = processInstanceResponse.Processes.Entities.Count;
            Entity activeProcessInstance   = processInstanceResponse.Processes.Entities[0]; // First record is the active process instance
            Guid   activeProcessInstanceID = activeProcessInstance.Id;                      // Id of the active process instance, which will be used later to retrieve the active path of the process instance

            // Retrieve the active stage ID of in the active process instance
            Guid activeStageID = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());

            // Retrieve the process stages in the active path of the current process instance
            RetrieveActivePathRequest pathReq = new RetrieveActivePathRequest
            {
                ProcessInstanceId = activeProcessInstanceID
            };
            RetrieveActivePathResponse pathResp = (RetrieveActivePathResponse)service.Execute(pathReq);


            // Retrieve the stage ID of the next stage that you want to set as active
            activeStageID = (Guid)pathResp.ProcessStages.Entities[4].Attributes["processstageid"];

            // Retrieve the process instance record to update its active stage
            ColumnSet cols1 = new ColumnSet();

            cols1.AddColumn("activestageid");
            Entity retrievedProcessInstance = service.Retrieve("opportunitysalesprocess", activeProcessInstanceID, cols1);

            // Set the next stage as the active stage
            retrievedProcessInstance["activestageid"] = new EntityReference(OpportunitySalesProcess.EntityLogicalName, activeStageID);
            service.Update(retrievedProcessInstance);
        }
        protected override void Execute(CodeActivityContext executionContext)
        {
            #region "Load CRM Service from context"

            Common objCommon = new Common(executionContext);
            objCommon.tracingService.Trace("Load CRM Service from context --- OK");
            #endregion

            #region "Read Parameters"
            String _ClonningRecordURL = this.ClonningRecordURL.Get(executionContext);
            if (_ClonningRecordURL == null || _ClonningRecordURL == "")
            {
                return;
            }
            string[] urlParts       = _ClonningRecordURL.Split("?".ToArray());
            string[] urlParams      = urlParts[1].Split("&".ToCharArray());
            string   objectTypeCode = urlParams[0].Replace("etc=", "");
            string   entityName     = objCommon.sGetEntityNameFromCode(objectTypeCode, objCommon.service);
            string   objectId       = urlParams[1].Replace("id=", "");
            objCommon.tracingService.Trace("ObjectTypeCode=" + objectTypeCode + "--ParentId=" + objectId);

            EntityReference process      = this.Process.Get(executionContext);
            string          processStage = this.ProcessStage.Get(executionContext);

            #endregion

            #region "SetProcessStage Execution"

            string stageName = processStage;

            Guid?stageId = null;
            if (processStage != null)
            {
                objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Process stage: " + stageName);
                Entity stageReference = new Entity("processstage");

                QueryExpression queryStage = new QueryExpression("processstage");
                queryStage.ColumnSet = new ColumnSet();
                queryStage.Criteria.AddCondition(new ConditionExpression(
                                                     "stagename",
                                                     ConditionOperator.Equal,
                                                     stageName));

                queryStage.Criteria.AddCondition(new ConditionExpression(
                                                     "processid",
                                                     ConditionOperator.Equal,
                                                     process.Id));

                objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Fetching the requested Stage.");
                try
                {
                    stageReference = objCommon.service.RetrieveMultiple(queryStage).Entities.FirstOrDefault();
                    if (stageReference == null)
                    {
                        throw new InvalidPluginExecutionException(
                                  "Process stage " + stageName + " not found");
                    }

                    stageId = stageReference.Id;
                }
                catch (Exception e)
                {
                    objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Error trying to retrieve " +
                                                   "the requested stage. Exception: " + e.ToString());
                    throw new InvalidPluginExecutionException("An error occurred while trying to fetch process stage " +
                                                              stageName +
                                                              ". Exception message: " + e.Message + ". Inner Exception: " + e.ToString());
                }
            }

            //*************************
            RetrieveProcessInstancesRequest procOpp1Req = new RetrieveProcessInstancesRequest
            {
                EntityId          = new Guid(objectId),
                EntityLogicalName = entityName
            };
            RetrieveProcessInstancesResponse procOpp1Resp = (RetrieveProcessInstancesResponse)objCommon.service.Execute(procOpp1Req);



            // Declare variables to store values returned in response
            Entity activeProcessInstance    = null;
            Guid   _processOpp1Id           = Guid.Empty;
            string _procInstanceLogicalName = "";
            if (procOpp1Resp.Processes.Entities.Count > 0)
            {
                activeProcessInstance = procOpp1Resp.Processes.Entities[0]; // First record is the active process instance
                _processOpp1Id        = activeProcessInstance.Id;           // Id of the active process instance, which will be used
                                                                            // later to retrieve the active path of the process instance

                Console.WriteLine("Current active process instance for the Opportunity record: '{0}'", activeProcessInstance["name"].ToString());

                // Get the BPF underlying entity logical name
                var uniqueProcessNameAttribute = "uniquename";
                var processEntity = objCommon.service.Retrieve("workflow", process.Id, new ColumnSet(uniqueProcessNameAttribute));
                _procInstanceLogicalName = processEntity.Attributes[uniqueProcessNameAttribute].ToString();

                //_procInstanceLogicalName = activeProcessInstance["name"].ToString().Replace(" ", string.Empty).ToLower(); // TO BE REMOVED: Incorrect as it only gets the display name.
            }
            else
            {
                Console.WriteLine("No process instances found for the opportunity record; aborting the sample.");
                Environment.Exit(1);
            }

            objCommon.tracingService.Trace("Starting the update");
            Entity processInstanceToUpdate = new Entity(_procInstanceLogicalName, _processOpp1Id);
            processInstanceToUpdate.Attributes.Add("activestageid", new EntityReference("processstage", stageId.Value));
            objCommon.tracingService.Trace("Starting the update2");
            objCommon.service.Update(processInstanceToUpdate);
            objCommon.tracingService.Trace("Starting the update3");
            //*************************

            /*
             * // Set the active process and the phase if defined
             * EntityReference objectReference = new EntityReference(entityName,new Guid(objectId));
             *
             * Entity entityToUpdate = new Entity();
             *
             * if (objectReference != null)
             * {
             *  entityToUpdate.LogicalName = objectReference.LogicalName;
             *  entityToUpdate.Id = objectReference.Id;
             *
             *  objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Case tu update Id = " + objectReference.Id.ToString() + ", Name = " + objectReference.Name);
             * }
             * else
             * {
             *  entityToUpdate.LogicalName = objCommon.context.PrimaryEntityName;
             *  entityToUpdate.Id = objCommon.context.PrimaryEntityId;
             *
             *  objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Case tu update Id = " + entityToUpdate.Id.ToString());
             * }
             *
             * entityToUpdate["processid"] = process.Id;
             * entityToUpdate["stageid"] = stageId.HasValue
             *  ? stageId.Value : default(Guid);
             *
             * try
             * {
             *  objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Updating " +
             *      " Case to Update Id = " + entityToUpdate.Id +
             *      " Process Id = " + process.Id + " | Process Name = " + process.Name +
             *      " Stage Id = " + stageId.Value.ToString());
             *
             *  objCommon.service.Update(entityToUpdate);
             *
             *  objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Case Id = " + entityToUpdate.Id.ToString() + " updated successfully.");
             * }
             * catch (Exception e)
             * {
             *  objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] Error while setting " +
             *      "the active BPF. Details: " + e.ToString());
             *  throw new InvalidPluginExecutionException("An error occurred while trying to update Business Process to Case Id = " + entityToUpdate.Id.ToString() +
             *      "Exception message " + e.Message +
             *      " Inner exception: " + e.ToString());
             * }
             * objCommon.tracingService.Trace("[Dynamics.ChangeBPFandPhase.Execute] End.");
             */
            #endregion
        }
Ejemplo n.º 7
0
        public void ChangeStage(IOrganizationService service)
        {
            // Get Process Instances
            var processInstanceRequest = new RetrieveProcessInstancesRequest
            {
                EntityId          = new Guid(IotAlert.Id.ToString()),
                EntityLogicalName = IotAlert.LogicalName.ToString()
            };

            var processInstanceResponse = (RetrieveProcessInstancesResponse)service.Execute(processInstanceRequest);

            // Declare variables to store values returned in response
            Entity activeProcessInstance   = processInstanceResponse.Processes.Entities[0]; // First record is the active process instance
            Guid   activeProcessInstanceID = activeProcessInstance.Id;                      // Id of the active process instance, which will be used later to retrieve the active path of the process instance

            // Retrieve the active stage ID of in the active process instance
            Guid activeStageID = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());

            // Retrieve the process stages in the active path of the current process instance
            RetrieveActivePathRequest pathReq = new RetrieveActivePathRequest
            {
                ProcessInstanceId = activeProcessInstanceID
            };
            RetrieveActivePathResponse pathResp = (RetrieveActivePathResponse)service.Execute(pathReq);

            var activeStageName     = "";
            var activeStagePosition = -1;

            Console.WriteLine("\nRetrieved stages in the active path of the process instance:");
            for (int i = 0; i < pathResp.ProcessStages.Entities.Count; i++)
            {
                // Retrieve the active stage name and active stage position based on the activeStageId for the process instance
                if (pathResp.ProcessStages.Entities[i].Attributes["processstageid"].ToString() == activeStageID.ToString())
                {
                    activeStageName     = pathResp.ProcessStages.Entities[i].Attributes["stagename"].ToString();
                    activeStagePosition = i;
                }
            }

            // Retrieve the stage ID of the next stage that you want to set as active
            if (activeStagePosition < pathResp.ProcessStages.Entities.Count)
            {
                activeStageID = (Guid)pathResp.ProcessStages.Entities[activeStagePosition + 1].Attributes["processstageid"];
            }
            else
            {
                Console.WriteLine("You are at latest stage");
                return;
            }

            // Retrieve IoT alert Id to match the specific bpf
            var query = new QueryExpression
            {
                EntityName = "msdyn_bpf_477c16f59170487b8b4dc895c5dcd09b",
                ColumnSet  = new ColumnSet("bpf_name", "bpf_msdyn_iotalertid", "activestageid")
            };
            // query.Criteria.AddCondition("processid", ConditionOperator.Equal, activeProcessInstanceID);
            var retrievedProcessInstanceList = service.RetrieveMultiple(query);

            foreach (var entity in retrievedProcessInstanceList.Entities)
            {
                var ioTAlertBpfER = (EntityReference)entity.Attributes["bpf_msdyn_iotalertid"];
                if (IotAlert.Id == ioTAlertBpfER.Id)
                {
                    RetrievedProcessInstance = entity;
                    break;
                }
            }

            //Retrieve Asset's account id
            var customerAsset        = (EntityReference)IotAlert.Attributes["msdyn_customerasset"];;
            var customerAssetIdQuery = new QueryExpression
            {
                EntityName = "msdyn_customerasset",
                ColumnSet  = new ColumnSet("msdyn_account", "msdyn_name", "msdyn_customerassetid"),
                Criteria   = new FilterExpression()
            };

            customerAssetIdQuery.Criteria.AddCondition("msdyn_customerassetid", ConditionOperator.Equal, customerAsset.Id);
            var customerAssetIdCollection = service.RetrieveMultiple(customerAssetIdQuery);

            AccountER = new EntityReference();
            if (customerAssetIdCollection.Entities.Count <= 1)
            {
                //TODO: need to confirm it is account or contact

                AccountER = (EntityReference)customerAssetIdCollection[0].Attributes["msdyn_account"];

                PrimaryAssetER.Id          = customerAssetIdCollection[0].Id;
                PrimaryAssetER.LogicalName = customerAssetIdCollection[0].LogicalName;
                PrimaryAssetER.Name        = customerAssetIdCollection[0].Attributes["msdyn_name"].ToString();
            }
            else
            {
                //more than one value, need developer to do investigation
                return;
            }

            // Retrieve the process instance record to update its active stage
            // activeStagePosition == 0 && activeStageName == "Created"
            CreateCase(service);
            // activeStagePosition == 1 && activeStageName == "Create Work Order"
            CreateWorkOrder(service);
            // activeStagePosition == 2 && activeStageName == "Schedule Work Order"
            ScheduleWorkOrder(service);

            // Set the next stage as the active stage
            // service.Update(RetrievedProcessInstance);
        }
        protected override void Execute(CodeActivityContext executionContext)
        {
            //*** Create the tracing service
            ITracingService tracingService = executionContext.GetExtension <ITracingService>();

            if (tracingService == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");
            }
            //*** Create the context
            IWorkflowContext context = executionContext.GetExtension <IWorkflowContext>();

            if (context == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve the workflow context.");
            }

            tracingService.Trace("{0}.Execute(): ActivityInstanceId: {1}; WorkflowInstanceId: {2}; CorrelationId: {3}; InitiatingUserId: {4} -- Entering", CHILD_CLASS_NAME, executionContext.ActivityInstanceId, executionContext.WorkflowInstanceId, context.CorrelationId, context.InitiatingUserId);

            IOrganizationServiceFactory serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>();
            IOrganizationService        serviceProxy   = serviceFactory.CreateOrganizationService(context.UserId);

            if (context.InputParameters.Contains(Common.Target) && context.InputParameters[Common.Target] is Entity)
            {
                try {
                    //*** Grab the Target Entity
                    var theEntity = (Entity)context.InputParameters[Common.Target];

                    tracingService.Trace("Active Stage Name: {0}", theEntity.EntityState);
                    //-------------------------------------------------------------------------------------------------------------
                    var processInstancesRequest = new RetrieveProcessInstancesRequest {
                        EntityId          = theEntity.Id,
                        EntityLogicalName = theEntity.LogicalName
                    };

                    var processInstancesResponse = (RetrieveProcessInstancesResponse)serviceProxy.Execute(processInstancesRequest);
                    var processCount             = processInstancesResponse.Processes.Entities.Count;

                    if (processCount > 0)
                    {
                        tracingService.Trace("{0}: Count of Process Instances concurrently associated with the Entity record: {1}", CHILD_CLASS_NAME, processCount);
                        tracingService.Trace("{0}: BPF Definition Name currently set for the Entity record: {1}, Id: {2}", CHILD_CLASS_NAME, processInstancesResponse.Processes.Entities[0].Attributes[CrmEarlyBound.Workflow.Fields.Name], processInstancesResponse.Processes.Entities[0].Id.ToString());

                        var bpfEntityRef = this.BpfEntityReference.Get <EntityReference>(executionContext);
                        var colSet       = new ColumnSet();
                        colSet.AddColumn(CrmEarlyBound.Workflow.Fields.UniqueName);
                        var bpfEntity = serviceProxy.Retrieve(bpfEntityRef.LogicalName, bpfEntityRef.Id, colSet);

                        tracingService.Trace("{0}: Switching to BPF Unique Name: {1}, Id: {2}", CHILD_CLASS_NAME, bpfEntity.Attributes[CrmEarlyBound.Workflow.Fields.UniqueName].ToString(), bpfEntity.Id.ToString());

                        var bpfStageName = this.BpfStageName.Get <string>(executionContext).Trim();
                        var qe           = new QueryExpression {
                            EntityName = CrmEarlyBound.Workflow.EntityLogicalName,
                            ColumnSet  = new ColumnSet(new string[] { CrmEarlyBound.Workflow.Fields.Name }),
                            Criteria   = new FilterExpression {
                                Conditions =
                                {
                                    new ConditionExpression {
                                        AttributeName = CrmEarlyBound.Workflow.Fields.UniqueName, Operator = ConditionOperator.Equal, Values ={ bpfEntity.Attributes[CrmEarlyBound.Workflow.Fields.UniqueName] } //new_bpf_472aceaabf7c4f1db4d13ac3c7076c65
                                    }
                                }
                            },
                            NoLock   = true,
                            Distinct = false
                        };

                        #region Convert Query Expression to FetchXML

                        var conversionRequest = new QueryExpressionToFetchXmlRequest {
                            Query = qe
                        };
                        var conversionResponse = (QueryExpressionToFetchXmlResponse)serviceProxy.Execute(conversionRequest);
                        var fetchXml           = conversionResponse.FetchXml;

                        tracingService.Trace("{0}: [{1}], Message: {2}", CHILD_CLASS_NAME, fetchXml, context.MessageName);

                        #endregion Convert the query expression to FetchXML.

                        tracingService.Trace("{0}: Built BPF Query, Now Executing...", CHILD_CLASS_NAME);

                        var entColByQuery = serviceProxy.RetrieveMultiple(qe).Entities; //// Execute Query with Filter Expressions
                        //-------------------------------------------------------------------------------------------------------------
                        if (entColByQuery != null && entColByQuery.Count > 0)           //// Search and handle related entities
                        {
                            tracingService.Trace("{0}: Found matching Business Process Flows...", CHILD_CLASS_NAME);

                            var bpfId         = new Guid();
                            var bpfEntityName = String.Empty;

                            foreach (var entity in entColByQuery) //// Loop related entities and retrieve Workflow Names
                            {
                                bpfId         = entity.Id;
                                bpfEntityName = entity.GetAttributeValue <string>(CrmEarlyBound.Workflow.Fields.Name);
                                break;
                            }

                            if (bpfId != Guid.Empty)
                            {
                                tracingService.Trace("{0}: Successfully retrieved the Business Process Flow that we'll be switching to: {1}, Id: {2}", CHILD_CLASS_NAME, bpfEntityName, bpfId.ToString());

                                System.Threading.Thread.Sleep(2000); // Wait for 2 seconds before switching the process
                                //*** Set to the new or same Business BpfEntityName Flow
                                var setProcReq = new SetProcessRequest {
                                    Target     = new EntityReference(theEntity.LogicalName, theEntity.Id),
                                    NewProcess = new EntityReference(CrmEarlyBound.Workflow.EntityLogicalName, bpfId)
                                };

                                tracingService.Trace("{0}: ***Ready To Update - Business Process Flow", CHILD_CLASS_NAME);
                                var setProcResp = (SetProcessResponse)serviceProxy.Execute(setProcReq);
                                tracingService.Trace("{0}: ***Updated", CHILD_CLASS_NAME);
                            }
                        }
                        else
                        {
                            tracingService.Trace("{0}: No Business Process Flows were found with Unique Name: {1}", CHILD_CLASS_NAME, bpfEntity.Attributes[CrmEarlyBound.Workflow.Fields.UniqueName].ToString());
                        }
                        //-------------------------------------------------------------------------------------------------------------
                        //*** Verify if the Process Instance was switched successfully for the Entity record
                        processInstancesRequest = new RetrieveProcessInstancesRequest {
                            EntityId          = theEntity.Id,
                            EntityLogicalName = theEntity.LogicalName
                        };

                        processInstancesResponse = (RetrieveProcessInstancesResponse)serviceProxy.Execute(processInstancesRequest);
                        processCount             = processInstancesResponse.Processes.Entities.Count;

                        if (processCount > 0)
                        {
                            var activeProcessInstance   = processInstancesResponse.Processes.Entities[0]; //*** First Entity record is the Active Process Instance
                            var activeProcessInstanceId = activeProcessInstance.Id;                       //*** Active Process Instance Id to be used later for retrieval of the active path of the process instance

                            tracingService.Trace("{0}: Successfully Switched to '{1}' BPF for the Entity Record.", CHILD_CLASS_NAME, activeProcessInstance.Attributes[CrmEarlyBound.Workflow.Fields.Name]);
                            tracingService.Trace("{0}: Count of process instances concurrently associated with the entity record: {1}.", CHILD_CLASS_NAME, processCount);
                            var message = "All process instances associated with the entity record:";

                            for (var i = 0; i < processCount; i++)
                            {
                                message = message + " " + processInstancesResponse.Processes.Entities[i].Attributes[CrmEarlyBound.Workflow.Fields.Name] + ",";
                            }

                            tracingService.Trace("{0}: {1}", CHILD_CLASS_NAME, message.TrimEnd(message[message.Length - 1]));

                            //*** Retrieve the Active Stage ID of the Active Process Instance
                            var activeStageId       = new Guid(activeProcessInstance.Attributes[CrmEarlyBound.ProcessStage.Fields.ProcessStageId].ToString());
                            var activeStagePosition = 0;
                            var newStageId          = new Guid();
                            var newStagePosition    = 0;

                            //*** Retrieve the BPF Stages in the active path of the Active Process Instance
                            var activePathRequest = new RetrieveActivePathRequest {
                                ProcessInstanceId = activeProcessInstanceId
                            };
                            var activePathResponse = (RetrieveActivePathResponse)serviceProxy.Execute(activePathRequest);

                            tracingService.Trace("{0}: Retrieved the BPF Stages in the Active Path of the Process Instance:", CHILD_CLASS_NAME);

                            for (var i = 0; i < activePathResponse.ProcessStages.Entities.Count; i++)
                            {
                                var curStageName = activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.StageName].ToString();

                                tracingService.Trace("{0}: Looping Through Stage #{1}: {2} (StageId: {3}, IndexId: {4})", CHILD_CLASS_NAME, i + 1, curStageName, activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.ProcessStageId], i);
                                //*** Retrieve the Active Stage Name and Stage Position based on a successful match of the activeStageId
                                if (activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.ProcessStageId].Equals(activeStageId))
                                {
                                    activeStagePosition = i;
                                    tracingService.Trace("{0}: Concerning the Process Instance -- Initial Active Stage Name: {1} (StageId: {2})", CHILD_CLASS_NAME, curStageName, activeStageId);
                                }
                                //*** Retrieve the New Stage Id, Stage Name, and Stage Position based on a successful match of the stagename
                                if (curStageName.Equals(bpfStageName, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    newStageId       = new Guid(activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.ProcessStageId].ToString());
                                    newStagePosition = i;
                                    tracingService.Trace("{0}: Concerning the Process Instance -- Desired New Stage Name: {1} (StageId: {2})", CHILD_CLASS_NAME, curStageName, newStageId);
                                }
                            }
                            //-------------------------------------------------------------------------------------------------------------
                            //***Update the Business Process Flow Instance record to the desired Active Stage
                            Entity    retrievedProcessInstance;
                            ColumnSet columnSet;
                            var       stageShift = newStagePosition - activeStagePosition;

                            if (stageShift > 0)
                            {
                                tracingService.Trace("{0}: Number of Stages Shifting Forward: {1}", CHILD_CLASS_NAME, stageShift);
                                //*** Stages only move in 1 direction --> Forward
                                for (var i = activeStagePosition; i <= newStagePosition; i++)
                                {
                                    System.Threading.Thread.Sleep(1000);
                                    //*** Retrieve the Stage Id of the next stage that you want to set as active
                                    var newStageName = activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.StageName].ToString();
                                    newStageId = new Guid(activePathResponse.ProcessStages.Entities[i].Attributes[CrmEarlyBound.ProcessStage.Fields.ProcessStageId].ToString());

                                    tracingService.Trace("{0}: Setting To Stage #{1}: {2} (StageId: {3}, IndexId: {4})", CHILD_CLASS_NAME, i + 1, newStageName, newStageId, i);
                                    //*** Retrieve the BpfEntityName Instance record to update its Active Stage
                                    columnSet = new ColumnSet();
                                    columnSet.AddColumn(ACTIVE_STAGE_ID);
                                    retrievedProcessInstance = serviceProxy.Retrieve(bpfEntity.Attributes[CrmEarlyBound.Workflow.Fields.UniqueName].ToString(), activeProcessInstanceId, columnSet);
                                    //*** Set the next Stage as the Active Stage
                                    retrievedProcessInstance[ACTIVE_STAGE_ID] = new EntityReference(CrmEarlyBound.ProcessStage.EntityLogicalName, newStageId); //(ProcessStage.EntityLogicalName, activeStageId);

                                    try {
                                        tracingService.Trace("{0}: ***Ready To Update -- BPF Stage", CHILD_CLASS_NAME);
                                        serviceProxy.Update(retrievedProcessInstance);
                                        tracingService.Trace("{0}: ***Updated", CHILD_CLASS_NAME);
                                    } catch (FaultException <OrganizationServiceFault> ex) { //*** Determine BPF Stage Requirements
                                        foreach (var stageAttribute in activePathResponse.ProcessStages.Entities[i].Attributes)
                                        {
                                            if (stageAttribute.Key.Equals("clientdata"))
                                            {
                                                tracingService.Trace("{0}: Attribute Key: {1}, Value: {2}", CHILD_CLASS_NAME, stageAttribute.Key, stageAttribute.Value.ToString());
                                                break;
                                            }
                                        }

                                        tracingService.Trace(FullStackTraceException.Create(ex).ToString());
                                        throw;
                                    }
                                }
                            }
                            else
                            {
                                tracingService.Trace("{0}: Number of Stages Shifting Backwards: {1}", CHILD_CLASS_NAME, stageShift);
                            }
                            //-------------------------------------------------------------------------------------------------------------
                            //***Retrieve the Business Process Flow Instance record again to verify its Active Stage information
                            columnSet = new ColumnSet();
                            columnSet.AddColumn(ACTIVE_STAGE_ID);
                            retrievedProcessInstance = serviceProxy.Retrieve(bpfEntity.Attributes[CrmEarlyBound.Workflow.Fields.UniqueName].ToString(), activeProcessInstanceId, columnSet);

                            var activeStageEntityRef = retrievedProcessInstance[ACTIVE_STAGE_ID] as EntityReference;

                            if (activeStageEntityRef != null)
                            {
                                if (activeStageEntityRef.Id.Equals(newStageId))
                                {
                                    tracingService.Trace("{0}: Concerning the Process Instance -- Modified -- Active Stage Name: {1} (StageId: {2})", CHILD_CLASS_NAME, activeStageEntityRef.Name, activeStageEntityRef.Id);
                                }
                            }
                        }
                        else
                        {
                            tracingService.Trace("{0}:The RetrieveProcessInstancesRequest object returned 0", CHILD_CLASS_NAME);
                        }
                    }
                } catch (FaultException <OrganizationServiceFault> ex) {
                    tracingService.Trace("{0}: Fault Exception: An Error Occurred During Workflow Activity Execution", CHILD_CLASS_NAME);
                    tracingService.Trace("{0}: Fault Timestamp: {1}", CHILD_CLASS_NAME, ex.Detail.Timestamp);
                    tracingService.Trace("{0}: Fault Code: {1}", CHILD_CLASS_NAME, ex.Detail.ErrorCode);
                    tracingService.Trace("{0}: Fault Message: {1}", CHILD_CLASS_NAME, ex.Detail.Message);
                    ////localContext.Trace("{0}: Fault Trace: {1}", this.ChildClassName, ex.Detail.TraceText);
                    tracingService.Trace("{0}: Fault Inner Exception: {1}", CHILD_CLASS_NAME, null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
                    //*** Display the details of the inner exception.
                    if (ex.InnerException != null)
                    {
                        Exception innerEx = ex;
                        var       i       = 0;
                        while (innerEx.InnerException != null)
                        {
                            innerEx = innerEx.InnerException;
                            tracingService.Trace("{0}: Inner Exception: {1}, Message: {2};", CHILD_CLASS_NAME, i++, innerEx.Message);
                        }
                    }

                    throw new InvalidPluginExecutionException(OperationStatus.Failed, ex.Detail.ErrorCode, ex.Message);
                } catch (Exception ex) {
                    tracingService.Trace("{0}: Exception: An Error Occurred During Workflow Activity Execution", CHILD_CLASS_NAME);
                    tracingService.Trace("{0}: Exception Message: {1}", CHILD_CLASS_NAME, ex.Message);
                    //*** Display the details of the inner exception.
                    if (ex.InnerException != null)
                    {
                        Exception innerEx = ex;
                        var       i       = 0;
                        while (innerEx.InnerException != null)
                        {
                            innerEx = innerEx.InnerException;
                            tracingService.Trace("{0}: Inner Exception: {1}, Message: {2};", CHILD_CLASS_NAME, i++, innerEx.Message);
                        }
                    }

                    throw new InvalidPluginExecutionException(OperationStatus.Failed, ex.HResult, ex.Message);
                } finally {
                    tracingService.Trace("{0}.Execute(): ActivityInstanceId: {1}; WorkflowInstanceId: {2}; CorrelationId: {3} -- Exiting", CHILD_CLASS_NAME, executionContext.ActivityInstanceId, executionContext.WorkflowInstanceId, context.CorrelationId);
                    // Uncomment to force plugin failure for Debugging
                    //--> throw new InvalidPluginExecutionException(String.Format("{0}.Execute(): Plug-in Warning: Manually forcing exception for logging purposes.", CHILD_CLASS_NAME));
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// </summary>
        /// <param name="serverConfig">Contains server connection information.</param>
        /// <param name="promptForDelete">When True, the user will be prompted to delete all
        /// created entities.</param>
        public void Run(ServerConnection.Configuration serverConfig, bool promptForDelete)
        {
            try
            {
                // Connect to the Organization service.
                // The using statement assures that the service proxy will be properly disposed.
                using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri, serverConfig.Credentials, serverConfig.DeviceCredentials))
                {
                    // This statement is required to enable early-bound type support.
                    _serviceProxy.EnableProxyTypes();

                    // Creates required records for this sample.
                    CreateRequiredRecords();

                    // Qualify a lead to create an opportunity
                    QualifyLeadRequest qualifyRequest = new QualifyLeadRequest
                    {
                        LeadId            = new EntityReference(Lead.EntityLogicalName, _leadId),
                        Status            = new OptionSetValue((int)lead_statuscode.Qualified),
                        CreateOpportunity = true
                    };
                    QualifyLeadResponse qualifyResponse = (QualifyLeadResponse)_serviceProxy.Execute(qualifyRequest);
                    _opportunityId = qualifyResponse.CreatedEntities[0].Id;
                    if (_opportunityId != Guid.Empty)
                    {
                        Console.WriteLine("\nQualified Lead to create an Opportunity record.");
                    }

                    // Verify the curently active BPF instance for the qualified Opportunity record
                    RetrieveProcessInstancesRequest procOpp1Req = new RetrieveProcessInstancesRequest
                    {
                        EntityId          = _opportunityId,
                        EntityLogicalName = Opportunity.EntityLogicalName
                    };
                    RetrieveProcessInstancesResponse procOpp1Resp = (RetrieveProcessInstancesResponse)_serviceProxy.Execute(procOpp1Req);

                    // Declare variables to store values returned in response
                    Entity activeProcessInstance = null;

                    if (procOpp1Resp.Processes.Entities.Count > 0)
                    {
                        activeProcessInstance = procOpp1Resp.Processes.Entities[0]; // First record is the active process instance
                        _processOpp1Id        = activeProcessInstance.Id;           // Id of the active process instance, which will be used
                                                                                    // later to retrieve the active path of the process instance

                        Console.WriteLine("Current active process instance for the Opportunity record: '{0}'", activeProcessInstance["name"].ToString());
                        _procInstanceLogicalName = activeProcessInstance["name"].ToString().Replace(" ", string.Empty).ToLower();
                    }
                    else
                    {
                        Console.WriteLine("No process instances found for the opportunity record; aborting the sample.");
                        Environment.Exit(1);
                    }

                    // Retrieve the active stage ID of the active process instance
                    _activeStageId = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());

                    // Retrieve the process stages in the active path of the current process instance
                    RetrieveActivePathRequest pathReq = new RetrieveActivePathRequest
                    {
                        ProcessInstanceId = _processOpp1Id
                    };
                    RetrieveActivePathResponse pathResp = (RetrieveActivePathResponse)_serviceProxy.Execute(pathReq);
                    Console.WriteLine("\nRetrieved stages in the active path of the process instance:");
                    for (int i = 0; i < pathResp.ProcessStages.Entities.Count; i++)
                    {
                        Console.WriteLine("\tStage {0}: {1} (StageId: {2})", i + 1,
                                          pathResp.ProcessStages.Entities[i].Attributes["stagename"], pathResp.ProcessStages.Entities[i].Attributes["processstageid"]);


                        // Retrieve the active stage name and active stage position based on the activeStageId for the process instance
                        if (pathResp.ProcessStages.Entities[i].Attributes["processstageid"].ToString() == _activeStageId.ToString())
                        {
                            _activeStageName     = pathResp.ProcessStages.Entities[i].Attributes["stagename"].ToString();
                            _activeStagePosition = i;
                        }
                    }

                    // Display the active stage name and Id
                    Console.WriteLine("\nActive stage for the process instance: '{0}' (StageID: {1})", _activeStageName, _activeStageId);

                    // Prompt the user to move to the next stage. If user choses to do so:
                    // Set the next stage (_activeStagePosition + 1) as the active stage for the process instance
                    bool moveToNextStage = true;
                    Console.WriteLine("\nDo you want to move to the next stage (y/n):");
                    String answer = Console.ReadLine();
                    moveToNextStage = (answer.StartsWith("y") || answer.StartsWith("Y"));
                    if (moveToNextStage)
                    {
                        // Retrieve the stage ID of the next stage that you want to set as active
                        _activeStageId = (Guid)pathResp.ProcessStages.Entities[_activeStagePosition + 1].Attributes["processstageid"];

                        // Retrieve the process instance record to update its active stage
                        ColumnSet cols1 = new ColumnSet();
                        cols1.AddColumn("activestageid");
                        Entity retrievedProcessInstance = _serviceProxy.Retrieve(_procInstanceLogicalName, _processOpp1Id, cols1);

                        // Update the active stage to the next stage
                        retrievedProcessInstance["activestageid"] = new EntityReference(ProcessStage.EntityLogicalName, _activeStageId);
                        _serviceProxy.Update(retrievedProcessInstance);


                        // Retrieve the process instance record again to verify its active stage information
                        ColumnSet cols2 = new ColumnSet();
                        cols2.AddColumn("activestageid");
                        Entity retrievedProcessInstance1 = _serviceProxy.Retrieve(_procInstanceLogicalName, _processOpp1Id, cols2);

                        EntityReference activeStageInfo = retrievedProcessInstance1["activestageid"] as EntityReference;
                        if (activeStageInfo.Id == _activeStageId)
                        {
                            Console.WriteLine("\nChanged active stage for the process instance to: '{0}' (StageID: {1})",
                                              activeStageInfo.Name, activeStageInfo.Id);
                        }
                    }

                    // Prompts to delete the required records
                    DeleteRequiredRecords(promptForDelete);
                }
            }

            // Catch any service fault exceptions that Microsoft Dynamics 365 throws.
            catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> )
            {
                // You can handle an exception here or pass it back to the calling method.
                throw;
            }
        }
        /// <summary>
        /// Executes the WorkFlow.
        /// </summary>
        /// <param name="crmWorkflowContext">The <see cref="LocalWorkflowContext"/> which contains the
        /// <param name="executionContext" > <see cref="CodeActivityContext"/>
        /// </param>
        /// <remarks>
        /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
        /// The WorkFlow's Execute method should be written to be stateless as the constructor
        /// is not called for every invocation of the WorkFlow. Also, multiple system threads
        /// could execute the WorkFlow at the same time. All per invocation state information
        /// is stored in the context. This means that you should not use global variables in WorkFlows.
        /// </remarks>
        public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext)
        {
            if (crmWorkflowContext == null)
            {
                throw new ArgumentNullException("crmWorkflowContext");
            }

            var bpfEntityName = this.BpfEntityName.Get <string>(executionContext);

            if (string.IsNullOrWhiteSpace(bpfEntityName))
            {
                return;
            }

            var stageName = this.StageName.Get <string>(executionContext);

            if (string.IsNullOrWhiteSpace(stageName))
            {
                return;
            }

            var tracingService = executionContext.GetExtension <ITracingService>();
            var service        = crmWorkflowContext.OrganizationService;
            var ctx            = crmWorkflowContext.WorkflowExecutionContext;

            tracingService.Trace(string.Format("BPF Entity is {0}", bpfEntityName));
            tracingService.Trace(string.Format("Primary Entity '{0}' with id={1}", ctx.PrimaryEntityName, ctx.PrimaryEntityId.ToString()));

            try
            {
                // Get the active Business Process Flow Instance
                var processInstanceReq = new RetrieveProcessInstancesRequest();
                processInstanceReq.EntityId          = ctx.PrimaryEntityId;
                processInstanceReq.EntityLogicalName = ctx.PrimaryEntityName;
                var    processInstanceResp   = (RetrieveProcessInstancesResponse)service.Execute(processInstanceReq);
                Entity activeProcessInstance = null;
                if (processInstanceResp != null && processInstanceResp.Processes.Entities.Count > 0)
                {
                    // First record is the active process instance
                    activeProcessInstance = processInstanceResp.Processes.Entities[0];

                    for (int i = 0; i < processInstanceResp.Processes.Entities.Count; i++)
                    {
                        var processInstance = processInstanceResp.Processes.Entities[i];
                        tracingService.Trace(string.Format("Name={0} id={1}", processInstance.Attributes["name"].ToString(), processInstance.Id.ToString()));
                    }
                }

                // Get the active Business Process Stage
                //var activeStageId = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());
                ////var activeProcessName = (string)activeProcessInstance.Attributes["processstageid"];

                //tracingService.Trace(string.Format("Got active process instance id={1} with stage id={0}", activeProcessInstance.Attributes["processstageid"].ToString(), activeProcessInstance.Id.ToString()));

                //// Retrieve the process stages in the active path of the current process instance
                //var pathReq = new RetrieveActivePathRequest();
                //pathReq.ProcessInstanceId = activeProcessInstance.Id;
                //RetrieveActivePathResponse pathResp = (RetrieveActivePathResponse)service.Execute(pathReq);

                //tracingService.Trace("Retrieved stages in the active path of the process instance:");

                //var activeStagePosition = 0;
                //var activeStageName = string.Empty;
                //var lastStagePosition = pathResp.ProcessStages.Entities.Count - 1;
                //for (int i = 0; i < pathResp.ProcessStages.Entities.Count; i++)
                //{
                //    tracingService.Trace(string.Format("Stage {0}: {1} (StageId: {2})", (i + 1).ToString(),
                //                            pathResp.ProcessStages.Entities[i].Attributes["stagename"].ToString(),
                //                            pathResp.ProcessStages.Entities[i].Attributes["processstageid"].ToString()));

                //    // Retrieve the active stage name and active stage position based on the activeStageId for the process instance
                //    if (pathResp.ProcessStages.Entities[i].Attributes["processstageid"].ToString() == activeStageId.ToString())
                //    {
                //        activeStageName = pathResp.ProcessStages.Entities[i].Attributes["stagename"].ToString();
                //        activeStagePosition = i;
                //    }
                //}

                //// Display the active stage name and Id
                //tracingService.Trace(string.Format("Stage {2} is active for the process instance: {0} (StageID: {1})", activeStageName, activeStageId, (activeStagePosition + 1).ToString()));

                //                if (activeStagePosition == lastStagePosition && direction == "next")
                //                {
                //                    tracingService.Trace("Already on last stage. Can't move to next stage.");
                //                }
                //                else if (activeStagePosition == 0 && direction == "previous")
                //                {
                //                    tracingService.Trace("Already on first stage. Can't move to first stage.");
                //                }
                //                else
                //                {
                // Retrieve the stage ID of the next stage that you want to set as active
                //                    var nextPosition = activeStagePosition + 1;
                //                    if (direction == "previous")
                //                    {
                //                        nextPosition = activeStagePosition - 1;
                //                    }

                //                    var nextStageId = (Guid)pathResp.ProcessStages.Entities[nextPosition].Attributes["processstageid"];

                //                    tracingService.Trace(string.Format("Stage {0} is next with id={1}", (nextPosition + 1).ToString(), nextStageId.ToString()));

                var processName = activeProcessInstance.Attributes["name"].ToString();
                var fetchXml    = string.Format(@"<fetch top='1' >
                                  <entity name='workflow' >
                                    <attribute name='workflowid' />
                                    <filter>
                                      <condition attribute='name' operator='eq' value='{0}' />
                                      <condition attribute='statecode' operator='eq' value='1' />
                                    </filter>
                                    <link-entity name='processstage' from='processid' to='workflowid' alias='stage' >
                                      <attribute name='processstageid' />
                                      <filter type='and' >
                                        <condition attribute='stagename' operator='eq' value='{1}' />
                                      </filter>
                                    </link-entity>
                                  </entity>
                                </fetch>", processName, stageName);

                tracingService.Trace(fetchXml);

                var process = Query.QueryCRMForSingleEntity(service, fetchXml);
                if (process == null)
                {
                    throw new InvalidPluginExecutionException(string.Format("Process {0} or Stage {1} does not exist", processName, stageName));
                }

                var nextStageId = (Guid)(process.GetAttributeValue <AliasedValue>("stage.processstageid")).Value;

                // Retrieve the process instance record to update its active stage
                var cols1 = new ColumnSet();
                cols1.AddColumn("activestageid");
                var retrievedProcessInstance = service.Retrieve(bpfEntityName, activeProcessInstance.Id, cols1);

//                    tracingService.Trace(string.Format("Active Stage Id is a lookup to {0}", pathResp.ProcessStages.Entities[nextPosition].LogicalName));

                // Set the next stage as the active stage
                retrievedProcessInstance["activestageid"] = new EntityReference(bpfEntityName, nextStageId);
                service.Update(retrievedProcessInstance);
                //              }
            }
            catch (Exception ex)
            {
                tracingService.Trace(string.Format("ERROR. Move Next Stage Activity: {0} {1}", ex.Message, ex.StackTrace));
                throw new InvalidPluginExecutionException("An error occured while moving to next stage. Please ask an administrator for further actions.");
            }
        }