public void Delegate_After_MandataryApproveTest() { // 发起流程 var department = SecurityContext.Provider.GetOrganization(loginUser.DeptId); Assert.IsNotNull(department); var instance = engine.CreateWorkflow(1); Assert.IsNotNull(instance); instance.Creator = loginUser.Name; instance.CreatorId = loginUser.Id; instance.CreatorDeptId = department.Id; instance.CreatorDeptName = department.FullName; instance.Title = "(委托单元测试)" + DateTime.Now.ToString("yyyyMMddHHmm"); var saveResult = engine.SaveWorkflow(instance); Assert.IsTrue(saveResult); var approveResult = new ApproveResult(); approveResult.Choice = "营销接口审核"; approveResult.Comment = "通过"; approveResult.NextUsers = new List<string>(){ loginUser.Id }; var runResult = engine.RunWorkflow(instance, approveResult); Assert.IsTrue(runResult); instanceNo = instance.InstanceNo; // 第二个环节的WorkItem表已添加被委托人信息 var instance2 = engine.LoadWorkflow(instance.InstanceNo, 2); var workitem2 = instance2.CurrentWorkItem; Assert.IsNotNull(instance2); Assert.IsNotNull(workitem2); Assert.IsNullOrEmpty(workitem2.MandataryId); // 添加委托 var mandatary = SecurityContext.Provider.GetUser("liangyanshan"); AddDelegateWork(loginUser, mandatary); // 设置流程的当前人为被委托人,然后提交流程 engine.SetCurrentUser(mandatary.LoginId); var approveResult2 = new ApproveResult(); approveResult2.Choice = "通过"; approveResult2.Comment = "通过"; approveResult2.NextUsers = new List<string>(){ mandatary.Id }; var runResult2 = engine.RunWorkflow(instance2, approveResult2); Assert.IsTrue(runResult2); var instance3 = engine.LoadWorkflow(instance2.InstanceNo, 2); var workitem3 = instance3.CurrentWorkItem; Assert.IsNotNull(instance3); Assert.IsNotNull(workitem3); Assert.AreEqual(mandatary.Id, workitem3.MandataryId); }
/// <summary> /// 办理流程 /// </summary> /// <param name="instance">流程实例</param> /// <param name="result">处理结果</param> /// <param name="listNextUsers">分配办理人员列表</param> /// <param name="tobeReadUsers">待阅人员</param> /// <remarks></remarks> /// <returns></returns> public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> listNextUsers, IList<IUser> tobeReadUsers);
/// <summary> /// 运行流程 /// </summary> /// <param name="instance">流程编号</param> /// <param name="result">审批结果</param> /// <returns></returns> /// <remarks> /// 根据用户选择的下一步骤,计算出下一环节的参与者并持久化到数据库 /// 1、检查流程数据的合法性(及权限) /// 2、根据Choice获取下一环节的定义(名称) /// 3、结束当前WorkflowItem /// 4、添加下一环节处理人的WorkItem(s)数据 /// ========================================================= /// 调用K2接口 /// </remarks> public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result);
public void ToBeReadTest() { Assert.IsNotNull(engine); var department = SecurityContext.Provider.GetOrganization(loginUser.DeptId); Assert.IsNotNull(department); var instance = engine.CreateWorkflow(1); Assert.IsNotNull(instance); instance.Creator = loginUser.Name; instance.CreatorId = loginUser.Id; instance.CreatorDeptId = department.Id; instance.CreatorDeptName = department.FullName; instance.Title = "(待阅单元测试)" + DateTime.Now.ToString("yyyyMMddHHmm"); var saveResult = engine.SaveWorkflow(instance); Assert.IsTrue(saveResult); var approveResult = new ApproveResult(); approveResult.Choice = "营销接口审核"; approveResult.Comment = "通过"; approveResult.NextUsers = new List<string>(){ loginUser.Id }; approveResult.NextTobeReadUsers = new string[]{ loginUser.Id }; var runResult = engine.RunWorkflow(instance, approveResult); Assert.IsTrue(runResult); instanceNo = instance.InstanceNo; var instance2 = engine.LoadWorkflow(instance.InstanceNo, 3); var workitem2 = instance2.CurrentWorkItem; Assert.IsNotNull(instance2); Assert.IsNotNull(workitem2); Assert.AreEqual(TaskStatus.ToRead, workitem2.TaskStatus); var approveResult2 = new ApproveResult(); approveResult2.Choice = "通过"; approveResult2.Comment = "通过"; approveResult2.NextUsers = new List<string>(){ loginUser.Id }; var runResult2 = engine.RunWorkflow(instance2, approveResult2); Assert.IsTrue(runResult2); var instance3 = engine.LoadWorkflow(instance2.InstanceNo, 3); var workitem3 = instance3.CurrentWorkItem; Assert.IsNotNull(instance3); Assert.IsNotNull(workitem3); Assert.AreEqual(TaskStatus.ToRead, workitem3.TaskStatus); }
public void SignTest() { Assert.IsNotNull(engine); var department = SecurityContext.Provider.GetOrganization(loginUser.DeptId); Assert.IsNotNull(department); var instance = engine.CreateWorkflow(1); Assert.IsNotNull(instance); instance.Creator = loginUser.Name; instance.CreatorId = loginUser.Id; instance.CreatorDeptId = department.Id; instance.CreatorDeptName = department.FullName; instance.Title = "(签收单元测试)" + DateTime.Now.ToString("yyyyMMddHHmm"); var saveResult = engine.SaveWorkflow(instance); Assert.IsTrue(saveResult); var approveResult = new ApproveResult(); approveResult.Choice = "营销接口审核"; approveResult.Comment = "通过"; approveResult.NextUsers = new List<string>(){ loginUser.Id }; var runResult = engine.RunWorkflow(instance, approveResult); Assert.IsTrue(runResult); instanceNo = instance.InstanceNo; engine.SignWorkflow(instance.InstanceNo, 2); var assertSignTime = DateTime.Now; var instance2 = engine.LoadWorkflow(instance.InstanceNo, 2); var workitem2 = instance2.CurrentWorkItem; Assert.IsNotNull(instance2); Assert.IsNotNull(workitem2); Assert.AreEqual(instance.Title, instance2.Title); Assert.IsTrue(workitem2.SignTime.HasValue); Assert.IsTrue(workitem2.SignTime.Value >= assertSignTime.AddSeconds(-5) && workitem2.SignTime.Value <= assertSignTime.AddSeconds(5)); }
public void PendingJobTodoTest() { var department = SecurityContext.Provider.GetOrganization(loginUser.DeptId); Assert.IsNotNull(department); var instance = engine.CreateWorkflow(1); Assert.IsNotNull(instance); instance.Creator = loginUser.Name; instance.CreatorId = loginUser.Id; instance.CreatorDeptId = department.Id; instance.CreatorDeptName = department.FullName; instance.Title = "(待办单元测试)" + DateTime.Now.ToString("yyyyMMddHHmm"); var saveResult = engine.SaveWorkflow(instance); Assert.IsTrue(saveResult); var approveResult = new ApproveResult(); approveResult.Choice = "营销接口审核"; approveResult.Comment = "通过"; approveResult.NextUsers = new List<string>(){ loginUser.Id }; var runResult = engine.RunWorkflow(instance, approveResult); Assert.IsTrue(runResult); var job = PendingJob.Get(instance.InstanceNo, 2); Assert.IsTrue(job.DoPush); Assert.IsNull(job.PushedTime); }
public void MultiApproveTest() { Assert.IsNotNull(engine); var user1 = SecurityContext.Provider.GetUser("liangyanshan"); var user2 = SecurityContext.Provider.GetUser("zhuyan"); var department = SecurityContext.Provider.GetOrganization(loginUser.DeptId); Assert.IsNotNull(department); var instance = engine.CreateWorkflow(1); Assert.IsNotNull(instance); instance.Creator = loginUser.Name; instance.CreatorId = loginUser.Id; instance.CreatorDeptId = department.Id; instance.CreatorDeptName = department.FullName; instance.Title = "(多人审核单元测试)" + DateTime.Now.ToString("yyyyMMddHHmm"); var saveResult = engine.SaveWorkflow(instance); Assert.IsTrue(saveResult); var approveResult = new ApproveResult(); approveResult.Choice = "营销接口审核"; approveResult.Comment = "通过"; approveResult.NextUsers = new List<string>(){ loginUser.Id, user1.Id, user2.Id }; var runResult = engine.RunWorkflow(instance, approveResult); Assert.IsTrue(runResult); instanceNo = instance.InstanceNo; engine.SetCurrentUser(user1.LoginId); var instance2 = engine.LoadWorkflow(instance.InstanceNo, 3); var workitem2 = instance2.CurrentWorkItem; Assert.IsNotNull(instance2); Assert.IsNotNull(workitem2); var approveResult2 = new ApproveResult(); approveResult2.Choice = "通过"; approveResult2.Comment = "通过"; approveResult2.NextUsers = new List<string>(){ loginUser.Id }; var run2Result = engine.RunWorkflow(instance2, approveResult2); Assert.IsTrue(run2Result); var instance3 = engine.LoadWorkflow(instance.InstanceNo, 3); var workitem3 = instance3.CurrentWorkItem; Assert.IsNotNull(instance3); Assert.IsNotNull(workitem3); Assert.IsTrue(workitem3.FinishTime.HasValue); Assert.IsFalse(workitem3.AutoFinished); }
/// <summary> /// 提交流程实例 /// </summary> /// <param name="instance">流程实例</param> /// <param name="result">办理操作</param> /// <remarks> /// 验证当办理人,K2办理成功后维护办理记录,流程实例,新增办理记录 /// requireFields: /// instance.CurrentWorkItem /// </remarks> /// <returns></returns> public override bool RunWorkflow(WorkflowInstance instance, ApproveResult result) { if (instance.CurrentWorkItem == null) { throw new ActivityNotFoundException(instance.InstanceNo, instance.CurrentActivity); } // 验证当前办理人员 // 非WorkItem默认用户,非被委托人,未设置委托信息 if (!instance.CurrentWorkItem.PartId.Equals(CurrentUser.Id, StringComparison.OrdinalIgnoreCase) && (!string.IsNullOrEmpty(instance.CurrentWorkItem.MandataryId) && !instance.CurrentWorkItem.MandataryId.Equals(CurrentUser.Id, StringComparison.OrdinalIgnoreCase)) && !DelegateWork.IsDelegate(instance.AppCode, instance.CurrentWorkItem.PartId, CurrentUser.Id)) { throw new UserNotFoundException("当前用户不是该环节的处理人"); } // 计算下一环节处理人 var currentActi = instance.GetCurrentActi(); var nextActi = currentActi.Transitions[result.Choice]; if (nextActi == null) { throw new ChoiceNotFoundException(instance.InstanceNo, currentActi.Name, result.Choice); } // 下一步骤人员 var nextStepUsers = new List<IUser>(); if (!nextActi.Name.Equals("结束", StringComparison.OrdinalIgnoreCase)) { if (result.NextUsers == null) { result.NextUsers = nextActi.Actor.Resolve(instance).Select(p => p.Id).ToList(); } if (result.NextUsers == null || result.NextUsers.Count == 0) { throw new UserNotFoundException(string.Format("未找到下一步骤{0}的处理人", nextActi.Name)); } nextStepUsers.AddRange(result.NextUsers.Select(userid => SecurityContext.Provider.Get(userid))); } // 下一步骤待阅人员 var tobeReadUsers = new List<IUser>(); if (result.NextTobeReadUsers != null && result.NextTobeReadUsers.Count > 0) { tobeReadUsers.AddRange(result.NextTobeReadUsers.Select(userid => SecurityContext.Provider.Get(userid))); } // 提交K2服务器 bool isK2Finished = ServerEngine.RunWorkflow(instance, result, nextStepUsers, null); if (!isK2Finished) { return false; } // 提交数据库更新 bool isDbFinished = DbEngine.RunWorkflow(instance, result, nextStepUsers, tobeReadUsers); if (!isDbFinished) { return false; } return true; }
/// <summary> /// 办理流程 /// </summary> /// <param name="instance">流程实例</param> /// <param name="result">处理结果</param> /// <param name="listNextUsers">分配办理人员列表</param> /// <param name="tobeReadUsers">待阅人员</param> /// <remarks></remarks> /// <returns></returns> public override bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> listNextUsers, IList<IUser> tobeReadUsers) { var loginUser = SecurityContext.User; var k2ProcInstId = int.Parse(instance.DataLocator); var actionName = result.Choice; using (Connection conn = ConnectHostServer()) { conn.ImpersonateUser(loginUser.LoginId); var filter = new WorklistCriteria(); filter.AddFilterField(WCField.ProcessID, WCCompare.Equal, k2ProcInstId); var k2Worklist = conn.OpenWorklist(filter); if (k2Worklist.Count == 0) throw new K2WorklistNotFoundException(k2ProcInstId, loginUser.LoginId); var worklist = conn.OpenWorklistItem(k2Worklist.Cast<WorklistItem>().First().SerialNumber); // 增加下一环节多个负责人 var doc = new System.Xml.XmlDocument(); var root = doc.CreateElement("UserAccounts"); doc.AppendChild(root); foreach (var approver in listNextUsers) { var userNode = doc.CreateElement("Account"); userNode.InnerText = approver.LoginId; root.AppendChild(userNode); } worklist.ProcessInstance.XmlFields["处理人"].Value = doc.OuterXml; if (!worklist.Actions.Contains(actionName)) throw new ActionNotFoundException(k2ProcInstId, actionName); worklist.Actions[actionName].Execute(true); if (worklist.Status == WorklistStatus.Completed) { return true; } } return false; }
/// <summary> /// 运行流程 /// </summary> /// <param name="instance">流程实例</param> /// <param name="result">处理结果</param> /// <param name="nextStepUsers">下一环节处理人</param> /// <param name="tobeReadUsers">待阅人员</param> /// <returns></returns> public override bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> nextStepUsers, IList<IUser> tobeReadUsers) { var nextWorkItems = new List<K2WorkflowItem>(); var nextTobeReadWorkItems = new List<K2WorkflowItem>(); IEnumerable<K2WorkflowItem> curWorkItems = new K2WorkflowItem[0]; var currentActi = instance.GetCurrentActi(); var nextActi = currentActi.Transitions[result.Choice]; #region 更新当前环节处理状态 curWorkItems = WorkflowItemFactory.GetAll<K2WorkflowItem>(instance.InstanceNo, instance.CurrentActivity); foreach (var workItem in curWorkItems) { if (workItem.TaskStatus != TaskStatus.Waiting) { continue; } if ((workItem.TaskId == instance.CurrentWorkItem.TaskId)) { workItem.Comment = result.Comment; workItem.AutoFinished = false; workItem.Choice = result.Choice; // 默认处理结果中有以下关键字的为退回,其他都为通过 var rejectWords = new[] { "不同意", "退回", "拒绝" }; var isReject = false; foreach (var word in rejectWords) { isReject = result.Choice.Contains(word); if (isReject) { break; } } workItem.TaskStatus = isReject ? TaskStatus.Reject : TaskStatus.Accept; if (workItem.PartId.Equals(CurrentUser.Id, StringComparison.OrdinalIgnoreCase)) { // 原审核人处理的话,就清空被委托人字段 workItem.Mandatary = null; workItem.MandataryId = null; } else if (workItem.MandataryId == null || !workItem.MandataryId.Equals(CurrentUser.Id, StringComparison.OrdinalIgnoreCase)) { // 先有待办后有委托关系的话,更新WorkItem的被委托人字段为当前用户 workItem.Mandatary = CurrentUser.Name; workItem.MandataryId = CurrentUser.Id; } } else { workItem.AutoFinished = true; //(默认当前办理方式是多选一) workItem.TaskStatus = TaskStatus.Finished; } workItem.FinishTime = DateTime.Now; } #endregion #region 添加下一环节待办流程项 var lastTaskId = this.GetWorkItemLastTaskId(instance.InstanceNo); foreach (var user in nextStepUsers) { var workItem = WorkflowItemFactory.Create<K2WorkflowItem>(); lastTaskId += 1; workItem.TaskId = lastTaskId; workItem.InstanceNo = instance.InstanceNo; workItem.PartId = user.Id; workItem.PartName = user.Name; workItem.PartDeptId = user.DeptId; var dept = SecurityContext.Provider.GetOrganization(user.DeptId); workItem.PartDeptName = (dept == null ? "" : dept.FullName); workItem.ReceTime = DateTime.Now; workItem.TaskStatus = TaskStatus.Waiting; workItem.CurrentActi = nextActi.Name; // 检查有效的委托关系 // 默认将第一个被委托用户添加到WorkItem中,暂时不考虑同时委托给多个人的情况 var delegateRelations = DelegateWork.GetByDeletagor(instance.AppCode, workItem.PartId); if (delegateRelations.Count > 0) { var firstRelation = delegateRelations[0]; workItem.Mandatary = firstRelation.Mandatary; workItem.MandataryId = firstRelation.MandataryId; } nextWorkItems.Add(workItem); } #endregion #region 添加下一环节待阅流程 foreach (var user in tobeReadUsers) { var workItem = WorkflowItemFactory.Create<K2WorkflowItem>(); lastTaskId += 1; workItem.TaskId = lastTaskId; workItem.InstanceNo = instance.InstanceNo; workItem.PartId = user.Id; workItem.PartName = user.Name; workItem.PartDeptId = user.DeptId; var dept = SecurityContext.Provider.GetOrganization(user.DeptId); workItem.PartDeptName = (dept == null ? "" : dept.FullName); workItem.ReceTime = DateTime.Now; workItem.TaskStatus = TaskStatus.ToRead; workItem.CurrentActi = nextActi.Name; nextTobeReadWorkItems.Add(workItem); } #endregion instance.CurrentActivity = nextActi.Name; if (nextActi.Name.Equals("结束", StringComparison.OrdinalIgnoreCase)) { instance.EndTime = DateTime.Now; instance.Status = InstanceStatus.Finished; } // 运行流程 using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) { //1.更新当前办理环节及其相关环节 foreach (var workItem in curWorkItems) { _dao.UpdateFields<K2WorkflowItem>(workItem, "FinishTime", "AutoFinished", "Choice", "Comment", "TaskStatus", "MandataryId", "Mandatary"); } //2.新增下一批办理环节 foreach (var workitem in nextWorkItems) { _dao.Insert<K2WorkflowItem>(workitem); } //3.新增下一批待阅环节 foreach (var workitem in nextTobeReadWorkItems) { _dao.Insert<K2WorkflowItem>(workitem); } //4.更新流程实例 _dao.UpdateFields<K2WorkflowInstance>(instance, "EndTime", "Status", "CurrentActivity"); transactionScope.Complete(); } // 推送待办已办 using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) { foreach (var workItem in curWorkItems) { // 结束待办 PendingJob.Finish(workItem.InstanceNo, workItem.TaskId); } //2.新增下一批办理环节 foreach (var workItem in nextWorkItems) { // 增加待办 PendingJob.Todo(workItem.InstanceNo, workItem.TaskId); } transactionScope.Complete(); } try { var opinion = new PersonalOpinion() { UserId = instance.CurrentWorkItem.PartId, Content = result.Comment }; opinion.AddUsedTimes(); } catch (Exception ex) { Logger.LogError("K2Client.DbEngine.RunWorkflow", ex, new {UserId = instance.CurrentWorkItem.PartId, Content = result.Comment}); } return true; }