Dynamic CRM 2013学习笔记(四十六)简单审批流的实现
前面介绍过自定义审批流:
Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示
Dynamic CRM 2013学习笔记(二十一)自定义审批流2 - 配置按钮
Dynamic CRM 2013学习笔记(三十二)自定义审批流3 - 节点及实体配置
Dynamic CRM 2013学习笔记(三十三)自定义审批流4 - 规则节点 -有分支的流程处理
Dynamic CRM 2013学习笔记(三十四)自定义审批流5 - 自动邮件通知
虽然灵活,功能强大,不用修改代码,完全用配置就可以搞定。
最近客户需要实现一个很简单的审批流,就有了这篇简单审批流的实现。
首先根据需求文档分析流程:
功能实现如下:
一、 添加字段
一个是让用户修改的审批状态,如果当前用户是审批人,放开审批状态字段,让用户审批或拒绝;值为 Pending, Approved, Rejected
一个是实体的状态,用户审批后根据业务逻辑来判断实体的状态;值为 Pending, Approved, Rejected
一个审批人字段,提交或用户修改了审批状态后,设置下一个审批人
另外可以设置几个隐藏审批人的字段,方便在插件里一次得出,js里就方便设置了(尽量避免在js里运行大量逻辑),如上图主要是把 sales director, gm 存下来
二. JS控制提交按钮和审批状态字段
1. 提交控制
AllowSubmit: function () {var currentUserId = Xrm.Page.context.getUserId();var userHasRole = HP.QuoteRibbon.UserHasRole(["Reginal Sales"], currentUserId);var Approver = Xrm.Page.getAttribute("tm_approver").getValue();var AccountTypeValue = Xrm.Page.getAttribute("wf_accounttype").getValue();var QuoteTypeValue = Xrm.Page.getAttribute("tm_quote_type").getValue();var TotalAmount = Xrm.Page.getAttribute("tm_total_amount").getValue() / 1000;var AccountType = {};AccountType.House = 3;var QuoteType = {};QuoteType.Standard = 1;QuoteType.Custom = 2;if (userHasRole && Approver == null) {if (TotalAmount < 100 && QuoteTypeValue == QuoteType.Custom && AccountTypeValue != AccountType.House) {return false;}return true;}else {return false;}},Submit: function () {var AccountTypeValue = Xrm.Page.getAttribute("wf_accounttype").getValue();var QuoteTypeValue = Xrm.Page.getAttribute("tm_quote_type").getValue();var TotalAmount = Xrm.Page.getAttribute("tm_total_amount").getValue() / 1000;var ApproverAttribute = Xrm.Page.getAttribute("tm_approver");var Approver = ApproverAttribute.getValue();var QuoteStatusAttribute = Xrm.Page.getAttribute("tm_quote_status");var ApprovalResultAttribute = Xrm.Page.getAttribute("tm_approval_result");var CentralizedValue = Xrm.Page.getAttribute("tm_centralized").getValue();var SubmitAttribute = Xrm.Page.getAttribute("tm_submit");SubmitAttribute.setSubmitMode("always");QuoteStatusAttribute.setSubmitMode("always");ApprovalResultAttribute.setSubmitMode("always");var AccountType = {};AccountType.House = 3;var QuoteType = {};QuoteType.Standard = 1;QuoteType.Custom = 2;var QuoteStatus = {};QuoteStatus.Pending = 1;QuoteStatus.Approved = 2;QuoteStatus.Rejected = 3;var ApprovalStatus = {};ApprovalStatus.Pending = 1;ApprovalStatus.Approved = 2;ApprovalStatus.Rejected = 3;if (QuoteTypeValue == QuoteType.Standard) {if (TotalAmount <= 500) {QuoteStatusAttribute.setValue(QuoteStatus.Approved);ApprovalResultAttribute.setValue(ApprovalStatus.Approved);}else {//var sd = HP.QuoteRibbon.GetSalesDirector();//var user = [{ "id": sd.guid, "name": sd.name, "entityType": sd.logicalName }];//ApproverAttribute.setValue(user);QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}}else {if (AccountTypeValue == AccountType.House) {if (TotalAmount < 500) {ApproverAttribute.setValue(CentralizedValue);QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}else if (TotalAmount >= 500) {//var sd = HP.QuoteRibbon.GetSalesDirector();//var user = [{ "id": sd.guid, "name": sd.name, "entityType": sd.logicalName }];//ApproverAttribute.setValue(user);QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}}else {if (TotalAmount >= 100 && TotalAmount < 500) {ApproverAttribute.setValue(CentralizedValue);QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}else if (TotalAmount >= 500) {//var sd = HP.QuoteRibbon.GetSalesDirector();//var user = [{ "id": sd.guid, "name": sd.name, "entityType": sd.logicalName }];//ApproverAttribute.setValue(user);QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}}}SubmitAttribute.setValue("Submit_" + new Date());Xrm.Page.data.entity.save();},
2. 审批状态修改事件
ApprovalResultChanged: function () {var ApprovalStatus = {};ApprovalStatus.Pending = 1;ApprovalStatus.Approved = 2;ApprovalStatus.Rejected = 3;var QuoteType = {};QuoteType.Standard = 1;QuoteType.Custom = 2;var QuoteStatus = {};QuoteStatus.Pending = 1;QuoteStatus.Approved = 2;QuoteStatus.Rejected = 3;var ApproverAttribute = Xrm.Page.getAttribute("tm_approver");var CentralizedValue = Xrm.Page.getAttribute("tm_centralized").getValue();var approvalResultValue = Xrm.Page.getAttribute("tm_approval_result").getValue();var QuoteStatusAttribute = Xrm.Page.getAttribute("tm_quote_status");var ApprovalResultAttribute = Xrm.Page.getAttribute("tm_approval_result");var GMValue = Xrm.Page.getAttribute("tm_gmid").getValue();var AccountTypeValue = Xrm.Page.getAttribute("wf_accounttype").getValue();var QuoteTypeValue = Xrm.Page.getAttribute("tm_quote_type").getValue();var TotalAmount = Xrm.Page.getAttribute("tm_total_amount").getValue() / 1000;QuoteStatusAttribute.setSubmitMode("always");ApproverAttribute.setSubmitMode("always");if (approvalResultValue == ApprovalStatus.Approved) {if (QuoteTypeValue == QuoteType.Standard) {if (TotalAmount >= 500 && TotalAmount < 1000) {QuoteStatusAttribute.setValue(QuoteStatus.Approved);//ApprovalResultAttribute.setValue(ApprovalStatus.Approved);}else if (TotalAmount >= 1000) {if (HP.QuoteForm.UserHasRole(["General Manager"]) == true) {QuoteStatusAttribute.setValue(QuoteStatus.Approved);//ApprovalResultAttribute.setValue(ApprovalStatus.Approved);}else {if (CentralizedValue && HP.QuoteForm.GuidsisEqual(Xrm.Page.context.getUserId(), CentralizedValue[0].id)) {HP.QuoteForm.SetLookupValue(ApproverAttribute, GMValue);}else {HP.QuoteForm.SetLookupValue(ApproverAttribute, CentralizedValue);}QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}}}else {if (TotalAmount < 1000) {QuoteStatusAttribute.setValue(QuoteStatus.Approved);//ApprovalResultAttribute.setValue(ApprovalStatus.Approved);}else if (TotalAmount >= 1000) {if (CentralizedValue && HP.QuoteForm.GuidsisEqual(Xrm.Page.context.getUserId(), CentralizedValue[0].id)) {QuoteStatusAttribute.setValue(QuoteStatus.Approved);//ApprovalResultAttribute.setValue(ApprovalStatus.Approved);}else {if (HP.QuoteForm.UserHasRole(["General Manager"]) == true) {HP.QuoteForm.SetLookupValue(ApproverAttribute, CentralizedValue);}else {HP.QuoteForm.SetLookupValue(ApproverAttribute, GMValue);}QuoteStatusAttribute.setValue(QuoteStatus.Pending);ApprovalResultAttribute.setValue(ApprovalStatus.Pending);}}}}else if (approvalResultValue == ApprovalStatus.Rejected) {ApproverAttribute.setValue(null);QuoteStatusAttribute.setValue(QuoteStatus.Rejected);//ApprovalResultAttribute.setValue(ApprovalStatus.Rejected);}},
三、插件设置审批人
为了在js里快速方便地设置下一个审批人,可以通过插件在后台来设置。当提交后,触发插件把下几个审批人放到隐藏字段里以供js快速赋值
if (entity.Contains("tm_submit"))
{
Entity preImageEntity = (Entity)context.PreEntityImages["PreImage"];
if (preImageEntity.Contains("tm_approval_result") && ((OptionSetValue)preImageEntity["tm_approval_result"]).Value == 2)
return;
CRMConfigHelper.CRMConfig crmConfig = CRMConfigHelper.InitialCRMConfig(context.OrganizationName);
string sql = string.Format(@"select top 1 op.new_product_line
from Quote q join Opportunity o on q.OpportunityId = o.OpportunityId
join wf_opportunityproduct op on o.OpportunityId = op.wf_OpportunityId
where op.wf_IncludeinForecast = 1 and q.QuoteId = '{0}'", entity.Id);
var dtPL = SqlHelper.SQLExecuteQuery(crmConfig.CRMSqlConnStr, sql).Tables[0];
if (dtPL.Rows.Count == 1 && dtPL.Rows[0]["new_product_line"] != null)
{
string productLine = dtPL.Rows[0]["new_product_line"].ToString();
sql = string.Format(@"select top 1 bu.new_nlt_sales_director 'NLTSD', bu.new_tm_sales_director 'TMSD'
from BusinessUnit bu
join SystemUser u on bu.BusinessUnitId = u.BusinessUnitId
where u.SystemUserId = '{0}'", context.UserId);
var dtSD = SqlHelper.SQLExecuteQuery(crmConfig.CRMSqlConnStr, sql).Tables[0];
if (dtSD.Rows.Count == 1)
{
if (productLine == "1") //TM
{
entity["tm_sales_directorid"] = new EntityReference("systemuser", Guid.Parse(dtSD.Rows[0]["TMSD"].ToString()));
}
else if (productLine == "2") //NLT
{
entity["tm_sales_directorid"] = new EntityReference("systemuser", Guid.Parse(dtSD.Rows[0]["NLTSD"].ToString()));
}
//if (preImageEntity["tm_approver"] == null )
{
entity["tm_approver"] = entity["tm_sales_directorid"];
}
}
}
//if (preImageEntity.Contains("tm_gmid") && preImageEntity["tm_gmid"] != null)
// return;
sql = @"select top 1 u.SystemUserId 'GM'
from SystemUser u
join SystemUserRoles ur on u.SystemUserId = ur.SystemUserId
join role r on r.RoleId = ur.RoleId
where r.Name = 'General Manager'";
var dtGM = SqlHelper.SQLExecuteQuery(crmConfig.CRMSqlConnStr, sql).Tables[0];
if (dtGM.Rows.Count == 1 && dtGM.Rows[0]["GM"] != null)
{
entity["tm_gmid"] = new EntityReference("systemuser", Guid.Parse(dtGM.Rows[0]["GM"].ToString()));
}
}
四、公用JS方法
1. 设置Lookup值
SetLookupValue: function (LookupAttribute, LookupValue) {
var lookupReference = [];
lookupReference[0] = {};
lookupReference[0].id = LookupValue[0].id;
lookupReference[0].entityType = LookupValue[0].entityType;
lookupReference[0].name = LookupValue[0].name;
LookupAttribute.setValue(lookupReference);
},
2. OData查询
ODataRetrieve: function (oDataString) {
var retrieveReq = new XMLHttpRequest();
retrieveReq.open("GET", encodeURI(Xrm.Page.context.getClientUrl() + "/XRMServices/2011/OrganizationData.svc/" + oDataString), false);
retrieveReq.setRequestHeader("Accept", "application/json");
retrieveReq.setRequestHeader("Content-Type", "application/json;charset=utf-8");
retrieveReq.send();
return JSON.parse(retrieveReq.responseText).d;
},
3. 当前用户是否有指定的角色
UserHasRole: function (roleNames) {
var ODataResult = HP.QuoteForm.ODataRetrieve("SystemUserSet?$select=systemuserroles_association/Name&$expand=systemuserroles_association&$filter=SystemUserId eq guid'" + Xrm.Page.context.getUserId() + "'");
if (ODataResult != null && ODataResult.results.length == 1 && ODataResult.results[0].systemuserroles_association.results.length > 0) {
var oDataRoles = ODataResult.results[0].systemuserroles_association.results;
for (var i = 0; i < oDataRoles.length; i++) {
for (var j = 0; j < roleNames.length; j++) {
if (oDataRoles[i].Name == roleNames[j]) {
return true;
}
}
}
}
return false;
},
4. 判断两个GUID是相同
GuidsisEqual: function (guid1, guid2) {
var isEqual = false;
if (guid1 != null && guid2 != null) {
isEqual = guid1.replace(/[{}]/g, "").toLowerCase() == guid2.replace(/[{}]/g, "").toLowerCase();
}
return isEqual;
},
Dynamic CRM 2013学习笔记(四十六)简单审批流的实现的更多相关文章
- Dynamic CRM 2013学习笔记(十六)用JS控制Tab可见,可用
一个Form里经常会有好几个Tab,有时要根据一些条件设置哪些Tab可用,可见.下面就介绍下如何用JS对Tab进行控制. 1. 控制可见 function setTabVisableByName( ...
- Dynamic CRM 2013学习笔记(十四)复制/克隆记录
经常有这样的需求,一个单据上有太多要填写的内容,有时还关联多个子单据,客户不想一个一个地填写,他们想从已有的单据上复制数据,克隆成一条新的记录.本文将介绍如何克隆一条记录,包括它的子单据以生成一条新的 ...
- Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件
上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多 ...
- Dynamic CRM 2013学习笔记(十)客户端几种查询数据方式比较
我们经常要在客户端进行数据查询,下面分别比较常用的几种查询方式:XMLHttpRequest, SDK.JQuery, SDK.Rest. XMLHttpRequest是最基本的调用方式,JQuery ...
- Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮
有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules ...
- Dynamic CRM 2013学习笔记(十五)报表设计:报表入门、开发工具及注意事项
本文是关于CRM 2013报表开发入门介绍,包括开发工具的使用,以及不同于普通Reporting service的相关注意事项. 一.CRM报表简介 报表有两种,SQL-based报表和Fetch-b ...
- Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示
CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点 ...
- Dynamic CRM 2013学习笔记 系列汇总
这里列出所有 Dynamic CRM 2013学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址: Dynamic CRM 2013学习笔记 系列汇总 ...
- Dynamic CRM 2013学习笔记(二十六)报表设计:Reporting Service报表 动态参数、参数多选全选、动态列、动态显示行字体颜色
上次介绍过CRM里开始报表的一些注意事项:Dynamic CRM 2013学习笔记(十五)报表入门.开发工具及注意事项,本文继续介绍报表里的一些动态效果:动态显示参数,参数是从数据库里查询出来的:参数 ...
随机推荐
- Python之路【第十九篇】:爬虫
Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...
- JAVA的Random类[转]
在实际的项目开发过程中,经常需要产生一些随机数值,例如网站登录中的校验数字等,或者需要以一定的几率实现某种效果,例如游戏程序中的物品掉落等. 在Java API中,在java.util包中专门提供了一 ...
- zabbix通过curl命令判断web服务是否正常并自动重启服务
zabbix通过curl命令判断web服务是否正常并自动重启服务 主要思路: 通过curl命令获取服务器响应码,如果正常返回200,不正常返回000 具体命令: curl -I -s -w " ...
- 自定义控件TextView
public class defineTextView extends TextView { Context context; public defineTextView(Context contex ...
- TortoiseSVN文件夹及文件状态图标不显示解决方法
win8 64位系统,原本svn是好用的,安装了klive金山快盘后,svn图标都不显示了.最后通过修改注册表解决: win+R调出运行框,输入regedit,打开注册表编辑器. HKEY_LOCAL ...
- asp.net下载文件方法
/// <summary> /// 下载 /// </summary> /// <param name="url"></param> ...
- Spring JDBC常用方法详细示例
Spring JDBC使用简单,代码简洁明了,非常适合快速开发的小型项目.下面对开发中常用的增删改查等方法逐一示例说明使用方法 1 环境准备 启动MySQL, 创建一个名为test的数据库 创建Mav ...
- 【IIS】 网站优化
[IIS] 网站优化 一. 从硬件入手,升级服务器的cpu,内存,硬盘 这是成本最低的方法,所以如果要优化,请先考虑下现有服务器的硬件能力是不是满足要求. 二. 从数据库入手 索引: 检查该建的索引建 ...
- Spring----->projects----->Spring Web Flow
1.概述(about Spring Web Folw) Spring Web Flow是spring社区一个子project Spring Web Flow builds on Spring MVC ...
- 使用max() 函数
/********************************* 代码功能:使用串口输出a和b的最大值 使用函数:max(a,b); 创作时间:2016*11*04 作者邮箱:jikexianfe ...