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学习笔记 系列汇总 ...
随机推荐
- 二十六:Struts2 和 spring整合
二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...
- python3抓取到的拉勾数据统计
趁着最近有时间写了个拉勾爬虫抓取了后端.前端和移动端技术岗位的数据,总共大约6多万条记录,对其取前十名进行统计 按地域划分: 可以看出北上广深杭的数量远远超出其它城市,机会相对较多 2. 按融资阶段来 ...
- IMoniker接口的MKParseDisplayName和 GetDisplayName的注意事项
IMoniker接口的MKParseDisplayName和 GetDisplayName的注意事项
- 关于Android开发手机连接不上电脑问题解决方案
1.当然首先你得将手机里的usb debug选项选上,否则lsusb是不会有你的设备的2. lsusb 查看usb设备id3. sudo vim /etc/udev/rules.d/51-androi ...
- POJ(3468)
A Simple Problem with Integers http://poj.org/problem?id=3468 #include <stdio.h> struct node { ...
- UVM Top Testbench
top testbench在top_tb中包含进所有的文件,将DUT放在top_tb中(例化DUT),连接好各个端口,提供clk时钟和rst_n复位信号.最主要的是要给组件中的虚接口设置接口,一般是给 ...
- C# 定制 Attribute 简单使用
所谓 “定制Attribute”,就是一个类的实例,它被序列化成驻留在元数据的一个字节流. 我们可以使用 Attribute 来保存注释: namespace AttributeDemo { [Att ...
- JAVA课程实验报告 实验三 敏捷开发与XP实践
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩: 指导教师:娄嘉 ...
- hdu 5791 (DP) Two
hdu 5791 Two Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- CentOS 6.3 安装 phpmyadmin
安装phpMyAdminphpMyAdmin是一个网络接口,通过它可以管理你的MySQL数据库.首先,我们使CentOS系统RPMForge软件库的phpMyAdmin,而不是官方的CentOS 6. ...