/// <summary>
        /// It is called by Process engine for adding theadtask related to task element.
        /// </summary>
        /// <param name="item"></param>
        public (ResultOperation result, List <sysBpmsThreadTask> listTask) AddThreadTask(sysBpmsTask item, bool isFirstTask)
        {
            ThreadTaskService        threadTaskService = new ThreadTaskService(base.UnitOfWork);
            ResultOperation          result            = new ResultOperation();
            List <sysBpmsThreadTask> listTask          = new List <sysBpmsThreadTask>();

            switch ((sysBpmsTask.e_TypeLU)item.TypeLU)
            {
            case sysBpmsTask.e_TypeLU.UserTask:
                if (item.MarkerTypeLU.HasValue)
                {
                    foreach (sysBpmsThreadTask threadTaskItem in threadTaskService.GetMultiInstanceTask(item, base.EngineSharedModel))
                    {
                        //if user has access to this method, set thread task access Info to userID
                        if (isFirstTask && this.CheckAccessByThreadTask(item, threadTaskItem, base.EngineSharedModel.CurrentThread.UserID, null))
                        {
                            threadTaskItem.UpdateAccessInfo(base.EngineSharedModel.CurrentThread.UserID, null);
                        }
                        threadTaskService.Add(threadTaskItem);
                        listTask.Add(threadTaskItem);
                    }
                }
                else
                {
                    sysBpmsThreadTask threadTask = new sysBpmsThreadTask();
                    threadTask.Update(base.EngineSharedModel.CurrentThreadID.Value, item.ID, DateTime.Now, null, string.Empty, 0, (int)sysBpmsThreadTask.e_StatusLU.New);
                    threadTaskService.SetAccessInfoTo(threadTask, item, base.EngineSharedModel);
                    //if user has access to this method, set thread task access Info to thread userID
                    if (isFirstTask && this.CheckAccessByThreadTask(item, threadTask, base.EngineSharedModel.CurrentThread.UserID, null))
                    {
                        threadTask.UpdateAccessInfo(base.EngineSharedModel.CurrentThread.UserID, null);
                    }

                    threadTaskService.Add(threadTask);
                    listTask.Add(threadTask);
                }
                break;
            }
            return(result, listTask);
        }
        public void SetAccessInfoTo(sysBpmsThreadTask threadTask, Domain.sysBpmsTask task, EngineSharedModel engineSharedModel)
        {
            if (task.OwnerTypeLU.HasValue)
            {
                switch ((sysBpmsTask.e_OwnerTypeLU)task.OwnerTypeLU)
                {
                case sysBpmsTask.e_OwnerTypeLU.User:
                    switch ((UserTaskRuleModel.e_UserAccessType)task.UserTaskRuleModel.AccessType)
                    {
                    case UserTaskRuleModel.e_UserAccessType.Static:
                        threadTask.UpdateAccessInfo(task.UserID.ToGuidObj(), null);
                        break;

                    case UserTaskRuleModel.e_UserAccessType.Variable:
                        Guid?variableUserID = new DataManageEngine(engineSharedModel, base.UnitOfWork).GetValueByBinding(task.UserTaskRuleModel.Variable).ToGuidObjNull();
                        if (!variableUserID.HasValue)
                        {
                            throw new Exception(LangUtility.Get("UserNotFound.Text", nameof(sysBpmsThreadTask)));
                        }

                        threadTask.UpdateAccessInfo(variableUserID, null);
                        break;
                    }
                    break;

                case sysBpmsTask.e_OwnerTypeLU.Role:
                    switch ((UserTaskRuleModel.e_RoleAccessType)task.UserTaskRuleModel.AccessType)
                    {
                    case UserTaskRuleModel.e_RoleAccessType.Static:
                        //if this userTask must be seen by requester user, this add thread userId to new threadTask
                        if (task.IsInRole(null, (int)sysBpmsDepartmentMember.e_RoleLU.Requester))
                        {
                            threadTask.UpdateAccessInfo(engineSharedModel.CurrentThread?.UserID, null);
                        }
                        else
                        {
                            threadTask.UpdateAccessInfo(null, task.GetDepartmentRoles);
                        }
                        break;

                    case UserTaskRuleModel.e_RoleAccessType.Variable:
                        string roleName = new DataManageEngine(engineSharedModel, base.UnitOfWork).GetValueByBinding(task.UserTaskRuleModel.Variable).ToStringObj();
                        if (string.IsNullOrWhiteSpace(roleName))
                        {
                            throw new Exception(LangUtility.Get("RoleNotFound.Text", nameof(sysBpmsThreadTask)));
                        }

                        task.SetRoleDepartment(roleName, task.UserTaskRuleModel.SpecificDepartmentId);
                        //if this userTask must be seen by requester user, this add thread userId to new threadTask
                        if (task.IsInRole(null, (int)sysBpmsDepartmentMember.e_RoleLU.Requester))
                        {
                            threadTask.UpdateAccessInfo(engineSharedModel.CurrentThread?.UserID, null);
                        }
                        else
                        {
                            threadTask.UpdateAccessInfo(null, task.GetDepartmentRoles);
                        }
                        break;

                    case UserTaskRuleModel.e_RoleAccessType.CorrespondentRole:
                        Guid?userId       = task.UserTaskRuleModel.UserType == (int)UserTaskRuleModel.e_UserType.CurrentUserID ? new UserService(base.UnitOfWork).GetInfo(engineSharedModel.CurrentUserName ?? "")?.ID : engineSharedModel.CurrentThread?.UserID;
                        Guid?departmentId = new AccessCodeHelper(base.UnitOfWork).GetDepartmentHierarchyByUserId(userId.ToGuidObj(), task.UserTaskRuleModel.RoleCode.ToIntObj(), task.UserTaskRuleModel.GoUpDepartment);
                        if (!departmentId.HasValue)
                        {
                            throw new Exception(LangUtility.Get("OrganizationNotFound.Text", nameof(sysBpmsThreadTask)));
                        }

                        threadTask.UpdateAccessInfo(null, new List <Tuple <Guid?, string> >()
                        {
                            new Tuple <Guid?, string>(departmentId, task.UserTaskRuleModel.RoleCode)
                        });
                        break;
                    }
                    break;
                }
            }
            else
            {
                throw new Exception(LangUtility.Get("NextNoAccessSetting.Text", nameof(sysBpmsThreadTask)));
            }
        }
        public List <sysBpmsThreadTask> GetMultiInstanceTask(Domain.sysBpmsTask task, EngineSharedModel engineSharedModel)
        {
            sysBpmsThreadTask        threadTask = null;
            List <sysBpmsThreadTask> list       = new List <sysBpmsThreadTask>();

            switch ((sysBpmsTask.e_OwnerTypeLU)task.OwnerTypeLU)
            {
            case sysBpmsTask.e_OwnerTypeLU.User:
                switch ((UserTaskRuleModel.e_UserAccessType)task.UserTaskRuleModel.AccessType)
                {
                case UserTaskRuleModel.e_UserAccessType.Static:
                case UserTaskRuleModel.e_UserAccessType.Variable:
                    string userId = task.UserID;
                    if (task.UserTaskRuleModel.AccessType == (int)UserTaskRuleModel.e_UserAccessType.Variable)
                    {
                        userId = new DataManageEngine(engineSharedModel, base.UnitOfWork).GetValueByBinding(task.UserTaskRuleModel.Variable).ToStringObj();
                    }
                    int i = 0;
                    foreach (string item in userId.Split(','))
                    {
                        threadTask = new sysBpmsThreadTask();
                        threadTask.Update(engineSharedModel.CurrentThreadID.Value, task.ID, DateTime.Now.AddSeconds(i++), null, string.Empty, 0, (int)sysBpmsThreadTask.e_StatusLU.New);
                        threadTask.UpdateAccessInfo(item.ToGuidObj(), null);
                        list.Add(threadTask);
                    }
                    break;
                }
                break;

            case sysBpmsTask.e_OwnerTypeLU.Role:
                switch ((UserTaskRuleModel.e_RoleAccessType)task.UserTaskRuleModel.AccessType)
                {
                case UserTaskRuleModel.e_RoleAccessType.Static:
                case UserTaskRuleModel.e_RoleAccessType.Variable:
                    if (task.UserTaskRuleModel.AccessType == (int)UserTaskRuleModel.e_RoleAccessType.Variable)
                    {
                        task.SetRoleDepartment(new DataManageEngine(engineSharedModel, base.UnitOfWork).GetValueByBinding(task.UserTaskRuleModel.Variable).ToStringObj(), task.UserTaskRuleModel.SpecificDepartmentId);
                    }
                    foreach (var item in task.GetDepartmentRoles)
                    {
                        List <Guid> users = new DepartmentMemberService(base.UnitOfWork).GetList(item.Item1, item.Item2.ToIntObj(), null).Select(c => c.UserID).ToList();
                        //It is used  for sequential task.
                        int i = 0;
                        foreach (Guid uId in users)
                        {
                            threadTask = new sysBpmsThreadTask();
                            threadTask.Update(engineSharedModel.CurrentThreadID.Value, task.ID, DateTime.Now.AddSeconds(i++), null, string.Empty, 0, (int)sysBpmsThreadTask.e_StatusLU.New);
                            threadTask.UpdateAccessInfo(uId, null);
                            list.Add(threadTask);
                        }
                    }
                    break;

                case UserTaskRuleModel.e_RoleAccessType.CorrespondentRole:

                    Guid?userId       = task.UserTaskRuleModel.UserType == (int)UserTaskRuleModel.e_UserType.CurrentUserID ? new UserService(base.UnitOfWork).GetInfo(engineSharedModel.CurrentUserName ?? "")?.ID : engineSharedModel.CurrentThread?.UserID;
                    Guid?departmentId = new AccessCodeHelper(base.UnitOfWork).GetDepartmentHierarchyByUserId(userId.ToGuidObj(), task.UserTaskRuleModel.RoleCode.ToIntObj(), task.UserTaskRuleModel.GoUpDepartment);
                    if (!departmentId.HasValue)
                    {
                        throw new Exception(LangUtility.Get("OrganizationNotFound.Text", nameof(sysBpmsThreadTask)));
                    }
                    {
                        List <Guid> users = new DepartmentMemberService(base.UnitOfWork).GetList(departmentId, task.UserTaskRuleModel.RoleCode.ToIntObj(), null).Select(c => c.UserID).ToList();
                        //It is used  for sequential task.
                        int i = 0;
                        foreach (Guid uId in users)
                        {
                            threadTask = new sysBpmsThreadTask();
                            threadTask.Update(engineSharedModel.CurrentThreadID.Value, task.ID, DateTime.Now.AddSeconds(i++), null, string.Empty, 0, (int)sysBpmsThreadTask.e_StatusLU.New);
                            threadTask.UpdateAccessInfo(uId, null);
                            list.Add(threadTask);
                        }
                    }
                    break;
                }

                break;
            }
            return(list);
        }