Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批
最近有个特殊的需求,客户想做二次审批,就是审批通过后,再走一次审批流程。最开始一想,这还不简单,审批通过后,直接把状态改成draft就完了,后来一试,发现一堆问题,比如第一次审批完后,界面是不允许修改的,直接改成draft就又可以修改了;再比如审批活动记录的查找以及死循环的问题等等。于是自己动手单独写了一个公用的再审批插件,下面介绍详细的实现步骤:
一、添加字段以控制再审批的次数
添加一个字段 new_approval_count, 再审批一次就把它加1。如果只要再审批一次,那么大于1就退出。
二、获取模板
ApproveTempleteHelper templetehelper = new ApproveTempleteHelper();
Entity approveTempleteEntity = templetehelper.GetApproveTemplete(service, importCurrentEntity.LogicalName);
/// <summary>
/// 获取审批模板
/// </summary>
/// <param name="service"></param>
/// <param name="entityName"></param>
/// <returns></returns>
public Entity GetApproveTemplete(IOrganizationService service, string entityName)
{
try
{
QueryExpression query = new QueryExpression(); query.EntityName = ApproveTempleteSchemaName;
query.ColumnSet.AllColumns = true; query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And; ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = ApproveTempleteEntityNameSchemaName;
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add(entityName);
query.Criteria.AddCondition(condition1); ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = StateCodeSchemaName;
condition2.Operator = ConditionOperator.Equal;
condition2.Values.Add(0);
query.Criteria.AddCondition(condition2); ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = ApproveTempleteDefaultFlagSchemaName;
condition3.Operator = ConditionOperator.Equal;
condition3.Values.Add(true);
query.Criteria.AddCondition(condition3); EntityCollection results = service.RetrieveMultiple(query);
if (results.Entities.Count > 0)
{
return results.Entities[0];
}
else
{
//throw new Exception("没有为该实体定义默认的审批工作流。");
throw new Exception("No custom default approval workflow for current entity");
}
}
catch (Exception ex)
{
throw new Exception(MethodBase.GetCurrentMethod().Name + " " + ex.Message);
}
}
三、获取节点
ApproveTempleteNodeHelper nodehelper = new ApproveTempleteNodeHelper();
Entity approveNode = nodehelper.GetBeginNodeEntity(service, (Guid)approveTempleteEntity["crm_approve_templeteid"]);
/// <summary>
/// 获取开始节点
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public Entity GetBeginNodeEntity(IOrganizationService service, Guid templeteId)
{
try
{
QueryExpression query = new QueryExpression(); query.EntityName = TempleteNodeSchemaName;
query.ColumnSet.AllColumns = true; query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And; ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = TempleteNodeClassSchemaName;
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add(0);
query.Criteria.AddCondition(condition1); ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = StateCodeSchemaName;
condition2.Operator = ConditionOperator.Equal;
condition2.Values.Add(0);
query.Criteria.AddCondition(condition2); ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = TempleteIDSchemaName;
condition3.Operator = ConditionOperator.Equal;
condition3.Values.Add(templeteId);
query.Criteria.AddCondition(condition3); EntityCollection results = service.RetrieveMultiple(query); if (results.Entities.Count > 0)
{
return results.Entities[0];
}
else
{
//throw new Exception("没有未改实体定义开始节点。");
throw new Exception("No begin activity");
}
}
catch (Exception ex)
{
throw new Exception(MethodBase.GetCurrentMethod().Name + " " + ex.Message);
}
}
四、创建Instance
ApproveInstanceHelper instanceHelper = new ApproveInstanceHelper();
Guid instanceId = instanceHelper.CreateApproveInstance(service, approveTempleteEntity, billEntityReference);
EntityReference instanceReference = new EntityReference(ApproveInstanceSchemaName, instanceId);
/// <summary>
/// 创建流程实例
/// </summary>
/// <param name="service"></param>
/// <param name="templeteEntity"></param>
/// <param name="subject"></param>
/// <param name="billEntity"></param>
/// <returns></returns>
public Guid CreateApproveInstance(IOrganizationService service, Entity templeteEntity, EntityReference billEntityReference)
{
try
{
Entity instance = new Entity(ApproveInstanceSchemaName); instance[ApproveInstanceTempleteIdSchemaName] = new EntityReference(templeteEntity.LogicalName, (Guid)templeteEntity[templeteEntity.LogicalName + "id"]);
instance[ApproveInstanceEntityNameSchemaName] = billEntityReference.LogicalName;
//EntityReference ef = new EntityReference(billEntity.LogicalName, (Guid)templeteEntity[billEntity.LogicalName + "id"]);
instance[ApproveInstanceBillObjectSchemaName] = billEntityReference;
instance[ApproveInstancecrmSubjectSchemaName] = DateTime.Now.ToString() + "流程实例";
instance[ApproveInstanceSubjectSchemaName] = DateTime.Now.ToString() + "流程实例";
return service.Create(instance);
}
catch (Exception ex)
{
throw new Exception(MethodBase.GetCurrentMethod().Name + " " + ex.Message);
}
}
五、更新业务表Instance
BillHelper billHelper = new BillHelper();
billHelper.SetBillWFInstance(service, importCurrentEntity, instanceReference, (string)approveTempleteEntity["crm_wf_instanceid_field"], "new_approval_count", iCount);
/// <summary>
/// 修改业务单据状态
/// </summary>
/// <param name="service"></param>
/// <param name="billEntity"></param>
/// <param name="instanceRefence"></param>
/// <param name="instanceField"></param>
public void SetBillWFInstance(IOrganizationService service, Entity billEntity, EntityReference instanceRefence, string instanceField, string sField, int sValue)
{
try
{
billEntity[sField] = Convert.ToDecimal(sValue); //审批计数
billEntity[instanceField] = instanceRefence;
service.Update(billEntity);
}
catch (Exception ex)
{
throw new Exception(MethodBase.GetCurrentMethod().Name + " " + ex.Message);
}
}
六、创建审批活动
CreateApproveActivityHelper helper = new CreateApproveActivityHelper();
helper.CreateBeginApproveActivity(service, approveTempleteEntity, approveNode, currentEntity, instanceReference, context.UserId, owner);
/// <summary>
/// 创建第一个审批活动
/// </summary>
/// <param name="service"></param>
/// <param name="approveTemplete"></param>
/// <param name="approveNode"></param>
/// <param name="billEntity"></param>
public void CreateBeginApproveActivity(IOrganizationService service, Entity approveTemplete, Entity approveNode, Entity billEntity, EntityReference instanceReference, Guid userid, EntityReference owner)
{
try
{
//获取下一个审批节点
ApproveTempleteNodeHelper nodeHelper = new ApproveTempleteNodeHelper();
ApproveNode BeginApproveNode = nodeHelper.GetApproveNode(approveNode);
BeginApproveNode.CallBackValue = 3; //change to draft awen
EntityReference billEntityReference = new EntityReference(billEntity.LogicalName, (Guid)billEntity[billEntity.LogicalName + "id"]);
BeginApproveNode.BillEntityReference = billEntityReference;
EntityReference approveNodeReference = new EntityReference(approveNode.LogicalName, (Guid)approveNode[approveNode.LogicalName + "id"]);
EntityReference approveTempleteReference = new EntityReference(approveTemplete.LogicalName, (Guid)approveTemplete[approveTemplete.LogicalName + "id"]); //更改业务单据中的状态
nodeHelper.ChangeBillStatus(service, BeginApproveNode, billEntity); string subjectField = "";
if (approveTemplete.Attributes.Keys.Contains(ApproveTempleteSubjectFieldSchemaName))
{
subjectField = (string)approveTemplete[ApproveTempleteSubjectFieldSchemaName];
} //主题
string subject = GetApproveActivitySuject(service, billEntityReference.LogicalName, subjectField, billEntityReference.Id); EntityReference userReference = new EntityReference("systemuser", userid); CreateApproveActivity(service, subject, billEntityReference, userReference, approveNodeReference, approveTempleteReference, instanceReference, 3, true, owner); }
catch (Exception ex)
{
throw new Exception(MethodBase.GetCurrentMethod().Name + " " + ex.Message);
}
}
最后记得注册这个插件时,要在step里加上一个image:
[置顶]Dynamic CRM 2013学习笔记 系列汇总 -- 持续更新中
Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批的更多相关文章
- Dynamic CRM 2013学习笔记(十五)报表设计:报表入门、开发工具及注意事项
本文是关于CRM 2013报表开发入门介绍,包括开发工具的使用,以及不同于普通Reporting service的相关注意事项. 一.CRM报表简介 报表有两种,SQL-based报表和Fetch-b ...
- Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件
上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多 ...
- Dynamic CRM 2013学习笔记(十四)复制/克隆记录
经常有这样的需求,一个单据上有太多要填写的内容,有时还关联多个子单据,客户不想一个一个地填写,他们想从已有的单据上复制数据,克隆成一条新的记录.本文将介绍如何克隆一条记录,包括它的子单据以生成一条新的 ...
- Dynamic CRM 2013学习笔记(十)客户端几种查询数据方式比较
我们经常要在客户端进行数据查询,下面分别比较常用的几种查询方式:XMLHttpRequest, SDK.JQuery, SDK.Rest. XMLHttpRequest是最基本的调用方式,JQuery ...
- Dynamic CRM 2013学习笔记(十六)用JS控制Tab可见,可用
一个Form里经常会有好几个Tab,有时要根据一些条件设置哪些Tab可用,可见.下面就介绍下如何用JS对Tab进行控制. 1. 控制可见 function setTabVisableByName( ...
- Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮
有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules ...
- Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示
CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点 ...
- Dynamic CRM 2013学习笔记(二十六)报表设计:Reporting Service报表 动态参数、参数多选全选、动态列、动态显示行字体颜色
上次介绍过CRM里开始报表的一些注意事项:Dynamic CRM 2013学习笔记(十五)报表入门.开发工具及注意事项,本文继续介绍报表里的一些动态效果:动态显示参数,参数是从数据库里查询出来的:参数 ...
- Dynamic CRM 2013学习笔记(二十九)报表设计:reporting service 报表开发常见问题
在报表开发过程中,经常会遇到各种各样的问题,比如The report cannot be displayed. (rsProcessingAborted),一点有意义的提示都没有:再就是分页问题,经常 ...
- Dynamic CRM 2013学习笔记 系列汇总
这里列出所有 Dynamic CRM 2013学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址: Dynamic CRM 2013学习笔记 系列汇总 ...
随机推荐
- 转:RealThinClient (RTC)是什么?
RealThinClient SDK是用于开发标准的HTTP(S)服务器,ISAPI扩展以及客户端的VCL控件.可用于Windows下的CodeGear Delphi 6-XE5. 功能描述 Abou ...
- 自己练习读取写入txt
读取文件中的内容生成一个list,然后修改list后再写会该文件文件中的格式是:AA,BB,CC,DDblist = []for line in open('a.txt'): blist.extend ...
- WinExec
WinAPI: WinExec - 运行外部程序 //声明 WinExec( lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/Syste ...
- VC++绘图时,利用双缓冲解决屏幕闪烁 转载
最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...
- 深入理解js——prototype原型
之前(深入理解js--一切皆是对象)中说道,函数也是一种对象.它也是属性的集合,你也可以对函数进行自定义属性.而JavaScript默认的给了函数一个属性--prototype(原型).每个函数都有一 ...
- okhttp3的使用
http://www.qingpingshan.com/rjbc/az/110232.html 请求队列,post? 待定 http://www.07net01.com/2015/12/1017279 ...
- scala 学习: case class
case class: 1.定义为case class 的类在实例化时,可以不使用new 关键字. case class People(name:String, age:Int) val zhangs ...
- oracle学习-存储过程返回一个值,和返回一个结果集
一.返回一个值 --创建存储过程 create or replace procedure sp_hu_test(spcode in varchar2,spname out varchar2)is be ...
- Oracle相关账户几个语句
Oracle安装完成后,在“开始”里找到SQL Plus运行,要求输入帐号和密码,用system/密码连接. 1.Oracle里有一个默认的scott账户密码tiger,用该账户连接: CONN 用户 ...
- 结合Apache和Tomcat实现集群和负载均衡
http://fableking.iteye.com/blog/360870 TomcatApacheJSP应用服务器Web 本文基本参考自 轻松实现Apache,Tomcat集群和负载均衡,经由实 ...