private void updateStateAsComplete(WorkflowInstance wf, string auditContext, Guid tenantId, IMessagingService bus)
 {
     var message = new RecordStateAction()
     {
         AuditContext = auditContext,
         CorrelationId = Guid.NewGuid(),
         State = wf.CurrentState.StateTemplate.StateName,
         StateId = wf.CurrentState.Id,
         TargetObjectId = wf.TargetObjectId,
         TargetObjectType = wf.TargetObjectType,
         TenantId = tenantId,
         WorkflowInstanceId = wf.Id,
         WorkflowTemplateName = wf.WorkflowTemplate.WorkflowName,
         Event = "All_Tasks_Completed"
     };
     RecordStateActionHandler(message);
 }
        public void RecordStateActionHandler(RecordStateAction message)
        {
            var workflowId = message.WorkflowInstanceId;
            var tenantId = message.TenantId;
            var auditContext = message.AuditContext;
            var objId = message.TargetObjectId;
            var objType = message.TargetObjectType;
            var stateEvent = message.Event;
            var state = message.State;

            using (var dataContext = new DataContext(message.TenantId, message.AuditContext))
            {
                try
                {
                    var data = Utils.GetWorkflowInstance(dataContext, workflowId, objId, objType);
                    var transition = data.WorkflowTemplate.EventsTypes.FirstOrDefault(x => x.Event == stateEvent && ((x.Type == EventType.EventLevel.GLOBAL) || (x.Type == EventType.EventLevel.STATE && x.ParentName == state)));

                    data = Utils.GetWorkflowInstance(dataContext, workflowId, objId, objType);
                    if (data == null)
                    {
                        return;
                    }
                    var stateData = data.States.Where(x => (x.Id == message.StateId)).FirstOrDefault();
                    if (stateData == null)
                    {
                        stateData = data.States.Where(x => (x.StateTemplate.StateName == message.State)).OrderByDescending(x => x.Id).FirstOrDefault();
                        if (stateData == null)
                        {
                            return;
                        }
                    }

                    WorkflowEvent newEvent = null;

                    if (transition != null)
                    {
                        newEvent = new WorkflowEvent()
                        {
                            EventDate = DateTime.UtcNow,
                            EventMetaData = null,
                            EventType = transition,
                            WorkflowInstance = data,
                            ExecutedBy = message.AuditContext,
                        };
                        if (transition.Type == EventType.EventLevel.GLOBAL)
                        {
                            newEvent.WorkflowParent = data;
                        }
                        else
                        {
                            newEvent.StateParent = stateData;
                        }
                        data.Events.Add(newEvent);
                    }
                    else
                    {
                        return;
                    }
                    if (data.CurrentState.Id == stateData.Id || data.WorkflowTemplate.EventsTypes.Count(x => x.Type == EventType.EventLevel.GLOBAL && x.Event == stateEvent) > 0)
                    {
                        if (transition != null)
                        {
                            var nextState = data.WorkflowTemplate.States.FirstOrDefault(x => x.StateName == transition.MoveTo);
                            if (nextState != null)
                            {

                                var previousState = data.CurrentState;
                                data.CurrentState.IsCurrent = false;
                                data.CurrentState = new State()
                                {
                                    LastState = nextState.LastState,
                                    MetaData = null,
                                    TransitionDate = DateTime.UtcNow,
                                    TransitionedBy = auditContext,
                                    TransitionEvent = newEvent,
                                    Tasks = new List<Models.Task>(),
                                    StateTemplate = nextState,
                                };
                                data.CurrentState.StateTemplate.Tasks.Where(x => x.FirstTask == true).ToList().ForEach(x =>
                                {
                                    data.CurrentState.Tasks.Add(new Models.Task()
                                    {
                                        IsCurrentTask = true,
                                        State = data.CurrentState,
                                        TaskTemplate = x,
                                        TransitionDate = DateTime.UtcNow,
                                        TransitionedBy = message.AuditContext,
                                        WorkflowInstance = data,
                                        LastTask = x.LastTask,
                                    });
                                }
                                );
                            }
                            data.Completed = data.CurrentState.LastState;
                            if (data.Completed)
                            {
                                data.EndDate = DateTime.UtcNow;
                            }
                            dataContext.SaveChanges();
                            Utils.PublishWorkflowState(_bus, data, message.AuditContext);
                            Utils.PublishNewTasks(_bus, data, message.AuditContext);

                        }
                    }
                    else
                    {
                        dataContext.SaveChanges();
                    }
                }
                catch (Exception exc)
                {
                }
            }
        }