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

审批过程中,经常要求自动发邮件:审批中要通知下一个审批人进行审批;审批完通知申请人已审批完;被拒绝后,要通知已批准的人和申请人。下面详细介绍如何实现一个自动发邮件的插件:

 

1. 根据审批状态来确定要通知哪个人或哪个角色

  • 状态为2 - 审批中时,查找下一个审批人
/// <summary>/// 下一个审批人/// </summary>/// <returns></returns>private List<Guid> GetNextStepPerson(){    //收件人    List<Guid> mailToList = new List<Guid>();    string fetchQuery = @"        <fetch mapping=‘logical‘ distinct=‘false‘>            <entity name=‘crm_approve_activity‘>                <attribute name=‘ownerid‘ />                <order attribute=‘createdon‘ descending=‘true‘ />                <filter type=‘and‘>                    <condition attribute=‘regardingobjectid‘ operator=‘eq‘  uitype=‘‘ value=‘{0}‘ />                    <condition attribute=‘crm_approve_state‘ operator=‘eq‘ value=‘2‘ />                </filter>            </entity>        </fetch>";

    FetchExpression fetchExp = new FetchExpression(string.Format(fetchQuery, entity.Id));    EntityCollection result = service.RetrieveMultiple(fetchExp);    if (result.Entities.Count == 0) return null;    foreach (Entity activity in result.Entities)    {        Guid ownerid = activity.GetAttributeValue<EntityReference>("ownerid").Id;        if (!mailToList.Contains(ownerid)) mailToList.Add(ownerid);    }    return mailToList;}

 

  • 状态为3 - 审批通过时,查找申请人
/// <summary>/// 获得提交人/// </summary>/// <returns></returns>private List<Guid> GetSubmitPerson(){    //收件人    List<Guid> mailToList = new List<Guid>();    string fetchQuery = @"        <fetch count=‘1‘ mapping=‘logical‘>            <entity name=‘crm_approve_activity‘>                <attribute name=‘ownerid‘ />                <order attribute=‘createdon‘ />                <filter type=‘and‘>                    <condition attribute=‘regardingobjectid‘ operator=‘eq‘  uitype=‘‘ value=‘{0}‘ />                    <condition attribute=‘crm_approve_state‘ operator=‘eq‘ value=‘1‘ />                </filter>            </entity>        </fetch>";

    FetchExpression fetchExp = new FetchExpression(string.Format(fetchQuery, entity.Id));    EntityCollection result = service.RetrieveMultiple(fetchExp);    if (result.Entities.Count == 0) return null;    foreach (Entity activity in result.Entities)    {        Guid ownerid = activity.GetAttributeValue<EntityReference>("ownerid").Id;        if (!mailToList.Contains(ownerid)) mailToList.Add(ownerid);    }    return mailToList;}

 

 

  • 状态为4 - 审批拒绝时,查找审批过的人,以及申请人
/// <summary>/// reject 后获得审批过的和单据创始人/// </summary>/// <returns></returns>private List<Guid> GetApprovedPerson(){    //收件人    List<Guid> mailToList = new List<Guid>();    string fetchQuery = @"        <fetch mapping=‘logical‘ distinct=‘false‘>            <entity name=‘crm_approve_activity‘>                <attribute name=‘ownerid‘ />                <order attribute=‘createdon‘ descending=‘true‘ />                <filter type=‘and‘>                    <condition attribute=‘regardingobjectid‘ operator=‘eq‘  uitype=‘‘ value=‘{0}‘ />                    <condition attribute=‘crm_approve_state‘ operator=‘eq‘ value=‘1‘ />                </filter>            </entity>        </fetch>";

    FetchExpression fetchExp = new FetchExpression(string.Format(fetchQuery, entity.Id));    EntityCollection result = service.RetrieveMultiple(fetchExp);    if (result.Entities.Count == 0) return null;    foreach (Entity activity in result.Entities)    {        Guid ownerid = activity.GetAttributeValue<EntityReference>("ownerid").Id;        if (!mailToList.Contains(ownerid)) mailToList.Add(ownerid);    }    return mailToList;}

 

2. 定义邮件模板

Entity curEntity = service.Retrieve(entity.LogicalName, entity.Id, new ColumnSet(m_Parameter, "ownerid"));

string subjectTxt = string.Empty;string formNumber = curEntity.GetAttributeValue<string>(m_Parameter);if (formNumber == null) formNumber = "";string fName = entityDisplayName + "(" + formNumber + ")";

StringBuilder body = new StringBuilder();body.AppendLine("<p>Dear {0},</p>");//收件人的 first namestring url = GetCRMServiceUrl() + "main.aspx?etn=" + entity.LogicalName    + "&pagetype=entityrecord&id=%7B" + entity.Id + "%7D";if (approvalStatus == 4){    subjectTxt = fName + " was rejected";    body.AppendLine(string.Format("For more information, please click on <a href=‘{0}‘ target=‘_blank‘>{1}</a></p>", url, fName));    body.AppendLine("<p>Best Regards</p>");    body.AppendLine("<p>CRM</p>");    // txt = "Reject";}else if (approvalStatus == 3){    subjectTxt = fName + " has been completed";    body.AppendLine(string.Format("<p>{0} has been completed. For more information, please click on <a href=‘{1}‘ target=‘_blank‘>{2}</a></p>", fName, url, fName));    body.AppendLine("<p>Best Regards</p>");    body.AppendLine("<p>CRM</p>");    //  txt = "Completed";}else if (approvalStatus == 2){    subjectTxt = "Please review and approve " + fName;    body.AppendLine(string.Format("<p> Please review and approve the {0} on <a href=‘{1}‘ target=‘_blank‘>{2}</a></p>", fName, url, fName));    body.AppendLine("<p>Thank you very much!</p>");    body.AppendLine("<p>Best Regards</p>");    body.AppendLine("<p>CRM</p>");}

 

3. 创建邮件实体

List<ActivityParty> fromList = new List<ActivityParty>();fromList.Add(new ActivityParty(){    PartyId = new EntityReference(SystemUser.EntityLogicalName, context.UserId),    ParticipationTypeMask = new OptionSetValue(8)});

foreach (Guid to in mailToList){    // to    List<ActivityParty> toList = new List<ActivityParty>();    toList.Add(new ActivityParty()    {        PartyId = new EntityReference(SystemUser.EntityLogicalName, to),        ParticipationTypeMask = new OptionSetValue(8)    });

    Email email = new Email();    email.From = fromList;    email.To = toList;    //email.Cc = cclist;    email.RegardingObjectId = new EntityReference(curEntity.LogicalName, curEntity.Id);    email.ActualDurationMinutes = 30;    email.IsWorkflowCreated = false;    email.Subject = subjectTxt;    SystemUser user = new SystemUser();    user.Attributes = service.Retrieve(SystemUser.EntityLogicalName, to,      new ColumnSet("firstname")).Attributes;    email.Description = string.Format(body.ToString(), user.FirstName);    email.Id = service.Create(email);    SendMail(service, email.Id);}

 

4. 发送邮件

SendEmailRequest sendEmailreq = new SendEmailRequest();sendEmailreq.EmailId = mailId;sendEmailreq.TrackingToken = "";sendEmailreq.IssueSend = true;SendEmailResponse sendEmailresp = (SendEmailResponse)service.Execute(sendEmailreq);

 

 

5. 注册插件

 

6. 错误处理

有一次系统重置后,发邮件的插件报了一个错:Cannot open Sql Encryption Symmetric Key because Symmetric Key password does not exist in Config DB

解决方法:

依次打开Settings->Data management –> Data Encryption

然后在上面红框里填上任意一个key即可

 

大功告成!

 

Dynamic CRM 2013学习笔记 系列汇总 -- 持续更新中

时间: 2024-08-04 18:11:19

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

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学习笔记(十五)报表入门、开发工具及注意事项

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

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学习笔记(十九)自定义审批流1 - 效果演示

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

JAVA学习笔记(三十四)- 字节打印流 PrintStream

PrintStream字节打印流 import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Reader; /* * Pri