小技巧 - 在服务端空操作(DoNothing)中,如何自动撤销工作流
金蝶云社区-JohnnyDing
JohnnyDing
2人赞赏了该文章 3,107次浏览 未经作者许可,禁止转载编辑于2015年09月01日 11:16:36

背景:
通过WebService、WebAPI等集成方式,撤销提交,如果已经启动了工作流,撤销提交工作流。

撤销(CancelAssign)操作本身仅仅处理单据状态切换,并不撤销终止工作流实例,必须要通过空操作 + 插件实现。

如下示例代码,用于演示如何判断单据是否启动了工作流,并据此进行撤销提交处理(本地验证通过):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;

// Kingdee.BOS.Workflow.Contracts.dll
using Kingdee.BOS.Workflow.Contracts;
// Kingdee.BOS.Workflow.Models.dll
using Kingdee.BOS.Workflow.Models.Template;
using Kingdee.BOS.Workflow.Models.EnumStatus;
using Kingdee.BOS.Workflow.Models.ServiceArgs;

namespace JDSample.ServicePlugIn.Operation
{
///


/// 演示在单据的空操作(DoNothing)上,自动撤销工作流
///

[Description("演示自动撤销工作流")]
public class S150901AutoCancalAssignOpPlug : AbstractOperationServicePlugIn
{
public override void OnAddValidators(AddValidatorsEventArgs e)
{
// 要求操作结束后,显示提示信息
this.OperationResult.IsShowMessage = true;
}

///
/// 操作完成后,事务未提交时,触发此事件
///

///
public override void EndOperationTransaction(EndOperationTransactionArgs e)
{
// 工作流撤销,不支持批量处理
string formId = this.BusinessInfo.GetForm().Id;
string billId = Convert.ToString(e.DataEntitys[0][0]);


// 首先判断单据是否已经有未完成的工作流
IProcInstService procInstService = Kingdee.BOS.Workflow.Contracts.ServiceFactory.GetProcInstService(this.Context);
bool isExistWFProcInst = procInstService.CheckUnCompletePrcInstExsit(this.Context, formId, billId);


IOperationResult cancelResult;
if (isExistWFProcInst == false)
{// 未启动工作流,进行普通的撤销

cancelResult = this.SetStatusOnly(billId);
}
else
{// 启动了工作流,需要撤销工作流提交
cancelResult = this.AbortProcInst(formId, billId);
}


// 合并处理结果
if (cancelResult.IsSuccess == true)
{
// 自动撤销成功,显示空操作本身的成功提示即可
}
else
{
cancelResult.MergeValidateErrors();
if (cancelResult.OperateResult == null)
{// 操作失败,但是并没有返回提示信息
throw new KDBusinessException("AutoCancel-001", "未知原因导致自动撤销失败!");
}
else
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("自动撤销失败,失败原因:");
foreach (var operateResult in cancelResult.OperateResult)
{
sb.AppendLine(operateResult.Message);
}
// 通过抛出错误的方式,中断操作,提示出失败原因
throw new KDBusinessException("AutoCancel-002", sb.ToString());
}
}
}


///
/// 未提交工作流,直接调用普通的状态切换服务
///

///
private IOperationResult SetStatusOnly(string billId)
{
// 构建操作可选参数对象:忽略交互性的警告提示
OperateOption cancelOption = OperateOption.Create();
cancelOption.SetIgnoreWarning(true);

// 构建单据主键参数
List> pkEntityIds = new List>();
pkEntityIds.Add(new KeyValuePair(billId, ""));

// 调用撤销操作:单据必须配置CancelAssign操作
ISetStatusService setStatusService = ServiceHelper.GetService();
IOperationResult cancelResult = setStatusService.SetBillStatus(this.Context,
this.BusinessInfo,
pkEntityIds,
null,
"CancelAssign",
cancelOption);

return cancelResult;
}


///
/// 提交了工作流,撤销工作流实例
///

///
///
private IOperationResult AbortProcInst(string formId, string billId)
{
// 读取待撤销的流程实例
// using Kingdee.BOS.Workflow.Models.ServiceArgs;
GetCancelAssignsArgs getCancelAssignsArgs = new GetCancelAssignsArgs();
getCancelAssignsArgs.GetByBill(formId, billId);
IAssignmentService assignService = Kingdee.BOS.Workflow.Contracts.ServiceFactory.GetAssignmentService(this.Context);
assignService.GetCancelAssigns(this.Context, getCancelAssignsArgs);

// 判断工作流实例是否允许被撤销:如已经被处理,则不允许撤销
if (getCancelAssignsArgs.ProcInstCanCancelAssigns.Count == 0)
{
throw new KDBusinessException("AutoCancel-003", "未找到允许撤销的工作流实例!");
}
else if (getCancelAssignsArgs.ProcInstCanCancelAssigns[0].CanAbortInstance == false)
{
throw new KDBusinessException("AutoCancel-004", "提交的工作流已经被处理,不允许撤销!");
}

string procInstId = getCancelAssignsArgs.ProcInstCanCancelAssigns[0].ProcessInstanceId;
// 构建操作可选参数对象:忽略交互性的警告提示
OperateOption cancelOption = OperateOption.Create();
cancelOption.SetIgnoreWarning(true);

// 设置撤销原因
cancelOption.SetVariableValue("canceldisposition", string.Empty);

// 撤销工作流实例
IProcInstService procInstService = Kingdee.BOS.Workflow.Contracts.ServiceFactory.GetProcInstService(this.Context);
IOperationResult cancelResult = procInstService.AbortProcInst(
this.Context,
new string[] { procInstId },
cancelOption);

return cancelResult;
}
}
}