Dynamic CRM 2013学习笔记(四十六)简单审批流的实现

前面介绍过自定义审批流:

Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示

Dynamic CRM 2013学习笔记(二十一)自定义审批流2 - 配置按钮

Dynamic CRM 2013学习笔记(三十二)自定义审批流3 - 节点及实体配置

Dynamic CRM 2013学习笔记(三十三)自定义审批流4 - 规则节点 -有分支的流程处理

Dynamic CRM 2013学习笔记(三十四)自定义审批流5 - 自动邮件通知

Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批

Dynamic CRM 2013学习笔记(三十七)自定义审批流7 - 初始化(整套审批流下载、安装)

虽然灵活,功能强大,不用修改代码,完全用配置就可以搞定。

最近客户需要实现一个很简单的审批流,就有了这篇简单审批流的实现。

首先根据需求文档分析流程:

功能实现如下:

一、 添加字段

一个是让用户修改的审批状态,如果当前用户是审批人,放开审批状态字段,让用户审批或拒绝;值为 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学习笔记 系列汇总

时间: 2024-08-03 15:40:24

Dynamic CRM 2013学习笔记(四十六)简单审批流的实现的相关文章

Dynamic CRM 2013学习笔记(十六)用JS控制Tab可见,可用

一个Form里经常会有好几个Tab,有时要根据一些条件设置哪些Tab可用,可见.下面就介绍下如何用JS对Tab进行控制. 1. 控制可见 function setTabVisableByName(tabName, flag) { var control = Xrm.Page.ui.tabs.get(tabName); control.setVisible(flag); } 这里flag是true或false 2. 控制可用 看了上面的可见代码,是不是以为可用也这么简单呢?其实我们把上面的setV

Dynamic CRM 2013学习笔记(十四)复制/克隆记录

经常有这样的需求,一个单据上有太多要填写的内容,有时还关联多个子单据,客户不想一个一个地填写,他们想从已有的单据上复制数据,克隆成一条新的记录.本文将介绍如何克隆一条记录,包括它的子单据以生成一条新的记录. 主要用到Microsoft.Xrm.Client.EntityExtensions.Clone方法来克隆数据,以及用OrganizationServiceContext来动态复制子单据的数据. 首先在界面上新加一个Clone的按钮,加一个new_clone的字段:点击按钮时,把new_clo

Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件

上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多实体要实现这个功能,有人觉得有点麻烦了,就不太喜欢这种方式,于是我写了一个通用的子表合计功能的通用插件,只用在注册插件时,填写不同的参数就可以实现这个功能了. 1. 首先看下效果: 2. 注册方法: 我们需要在子表上对create和update方法进行注册: 注册时要填写4个参数: 第一个参数是要被

Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮

有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules –> CustomRule 用js来控制按钮是否显示:   js function: 首先用odata取出主表的状态,然后根据主表的状态来判断是否显示: var approvalStatus = null; function controlUpload(){ var marketingPlan =

Dynamic CRM 2013学习笔记(十)客户端几种查询数据方式比较

我们经常要在客户端进行数据查询,下面分别比较常用的几种查询方式:XMLHttpRequest, SDK.JQuery, SDK.Rest. XMLHttpRequest是最基本的调用方式,JQuery和Rest的二种方式其实也是用的XMLHttpRequest,只不过是把它封装了一下 JQuery和Rest二种方式的接口一样,所以调用方式也一样 1. XMLHttpRequest 定义 1: function ODataRetrieve(oDataString) { 2: var ServerU

Dynamic CRM 2013学习笔记(十五)报表入门、开发工具及注意事项

本文是关于CRM 2013报表开发入门介绍,包括开发工具的使用,以及不同于普通Reporting service的相关注意事项.   一.CRM报表简介 报表有两种,SQL-based报表和Fetch-based报表,区别如下: 区域 SQL-based 报表 Fetch-based 报表 Data Provider <DataProvider> 元素的值设置为SQL. 示例如下:<DataProvider>SQL</DataProvider> 报表RDL文件中的 &l

Dynamic CRM 2013学习笔记(十九)自定义审批流 - 效果演示

CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点,这里只有5个节点,而且没有规则节点(后面会介绍):   接着就是对上面的流程节点配置关系,这里就指定流程节点的走向:   运行一段时间后,可以查看审批的实例:   2. 操作审批流 审批流模板创建完后,我们就可以进行审批活动了. 开始的状态是Draft,这时可以提交审批: 点击Submit 按钮后

Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示

CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点,这里只有5个节点,而且没有规则节点(后面会介绍): 接着就是对上面的流程节点配置关系,这里就指定流程节点的走向: 运行一段时间后,可以查看审批的实例: 2. 操作审批流 审批流模板创建完后,我们就可以进行审批活动了. 开始的状态是Draft,这时可以提交审批: 点击Submit 按钮后,会提示是否

Dynamic CRM 2013学习笔记(二十六)Reporting Service报表 动态参数、参数多选全选、动态列、动态显示行字体颜色

上次介绍过CRM里开始报表的一些注意事项:Dynamic CRM 2013学习笔记(十五)报表入门.开发工具及注意事项,本文继续介绍报表里的一些动态效果:动态显示参数,参数是从数据库里查询出来的:参数可以多选或全选:动态地显示列,列不是固定的:根据某一字段的值来动态地显示整行字体的颜色. 下面介绍详细的方法: 一.动态参数.参数多选全选 动态参数: 首先定义一个Dataset: SELECT DISTINCT new_countryId, new_codename AS name FROM ne