AX2012提供两种类型的Alert,Change-based alert和Due-date-based alert,前者用于在对新建记录、删除记录、记录的某个指定字段被改变的时候发出提醒,后者则是用于监视记录日期类型的某个字段,在超期指定的日期后发出提醒。在记录的编辑form或者list page上右键菜单中我们能找到“Create alert rule”菜单项,通过它打开alert规则创建窗口。规则创建窗口里我们可以选择alert要发给谁,只能是一个特定的用户,不能是一个用户组,如果通知需要发送给多个用户只能创建多个alert规则了。另外在我们可以勾选“Send email”将通知通过邮件的方式发送给用户,要使用这个功能必须设置好Alert邮件模板,首先在Organization administration>Setup>Email-template创建一个Alert的邮件模板(非系统邮件模板),邮件模板中可以添加占位符变量,在生成具体的邮件时指向真实的数据。Alert邮件模板的例子可以在https://technet.microsoft.com/en-us/library/aa834376.aspx找到。创建好邮件模板后,我们还需要到Organization administration>Setup>Alerts>Alert parameter选择这个邮件模板为我们的Alert邮件模板。所有的通知规则我们可以在Organization administration>Setup>Alerts>Alert rules找到,在这里可以管理创建好的通知规则,使能或者删除规则等。通知规则列表有一列叫做Organiztion-wide,这个不是能手工修改的,如果我们对公司无关的表(比如workers、products)添加规则时会自动打勾。

通知规则创建好后不等于在记录改变时你就能收到Alert消息,我们还需要配置两个Batch job,由它们来处理发出通知消息。一个是 System administration>Periodic>Alerts> Change based alerts,由它处理change-based通知。另一个是 System administration>Periodic>Alerts>Due date alerts,由它出来due-date-based通知。

先来看Change-based的批处理任务,它运行的类是EventJobCUD,它只是判断EventCUD表中是否要处理的Alert事件,如果有则交由EventJobCUDTask处理。EventJobCUDTask读取EventCUD需要处理的记录的用户ID,通过runas切换到该用户运行EventJobCUDTask.runCudEventsForUser(),runCudEventsForUser依次读取该用户相关的EventCUD记录,然后交由EventProcessorCUD处理。EventProcessorCUD针对事件的类型(更新、删除、创建、主键更改)做不同的处理,比如更新事件,它从EventCUD的Data字段(Container类型)剥离出被监视记录字段的字段ID、新老值,创建EventTypeCUD对象,保存更新字段的新老值,随后根据通知规则中的通知类型创建相应的EventAction,最后生成相应的事件通知保存在EventInbox表中。如果指定了使用邮件通知,会创建EventActionEmail对象,它负责生成占位符对象数据映射,交由SysEmailTable或者SysEmailSystemTable生成实际的邮件放到SysOutgoingEmailTable等候发送。处理成功后相关记录在EventCUD中被删除。这里只是对处理过程做了简单的陈述,实际的过程要复杂得多,需要处理表继承已经通知规则中指定的记录过滤查询等。

可以看出change-based通知的核心是处理EventCUD的记录,那么这个表中的数据是从哪里来的呢?微软的解释是使用database log来检测记录更改,alert模块在xApplication类的EventInsert、EventUpdate、EventDelete注册自己的回调函数,如果通知规则中涉及到的表发生变化将更改记录到EventCUD表。可以看到的是如果我们添加一个通知规则,在表DatabaseLog中会相应增加一条记录,记录对哪个表做EventXXX类型的log。System administration > Setup > Database > Database log setup看不到这些记录,这个form不显示和EventXXX类型的DatabaseLog。在通知规则监视的表记录修改后,其修改记录在System administration > Inquries > Database > Database log也是看不到的,但是在EventCUD中会增加相关记录。xApplication是系统类,看不到具体是如何实现的。

再来看Due-Date-based的批处理任务,它运行的是EventJobDueDate,它读取EventRule表中Due-date类型的通知规则的用户ID,也是runas切换到该用户执行runDueDateEventsForUser(),在runDueDateEventsForUser中调用EventProcessorDueDate.processRule()来处理当前的EventRule,从EventRule中读取记录过滤Query,读取Query中的记录,调用EventProcessorDueDate.processRecord()处理记录,如果日期字段超期,也是根据通知规则中的通知类型创建相应的EventAction,后面的过程和change-based类似了。如果通知规则已经触发并成功处理,该通知规则会被添加到表EventRuleIgnore中,后续不再触发(在EventTypeDue.canExecute()判断)。

在了解了Alert如何工作的后,我们可以添加自定义的事件类型(EventType)和自定义的事件处理动作(EventAction),可以参见https://msdn.microsoft.com/en-us/library/aa673670.aspx

通知消息是保存在表EventInbox中的,在user options的Notification一节我们可以设置接受通知的时间间隔,客户端按照时间间隔读取通知消息,如果通知设置了需要显示弹窗,AX client会弹出弹窗。可以想见的是直接操作EventInbox来创建用户通知,网上有很多例子,这里截取一个(http://daxldsoft.blogspot.com/2012/10/create-custom-alert-for-ax-with-go-to.html):

 public static void CreateAlert(str message,
str subject,
UserId userId = curUserId(),
NoYes showPopup = NoYes::Yes,
NoYes sendEmail = NoYes::No,
Common record = null,
str dataSourcename = '',
MenuFunction menuFunction = null)
{
EventInbox inbox;
DictTable table;
EventContextInformation eci;
EventInboxData inboxData;
Args args = new Args();
List list;
EventInboxId inboxId = EventInbox::nextEventId();
FormRun formRun;
WorkflowRecordCaptionGenerator recordCaptionGenerator;
UserInfo userInfo;
inboxId = EventInbox::nextEventId();
inbox.initValue();
inbox.ShowPopup = showPopup;
inbox.Subject = subject;
inbox.Message = message;
inbox.SendEmail = sendEmail;
inbox.EmailRecipient = SysUserInfo::find().Email;
inbox.UserId = userId;
inbox.InboxId = inboxId;
inbox.AlertCreatedDateTime = DateTimeUtil::getSystemDateTime();
if (record)
{
table = new DictTable(record.TableId);
eci = new EventContextInformation();
if (!menuFunction)
{
menuFunction = new MenuFunction(table.formRef(),MenuItemType::Display);
if (!menuFunction)
throw error(strFmt("@SYS104114",table.formRef()));
}
//Build the data to drill down to from the notification
args.menuItemName(menuFunction.name());
args.menuItemType(MenuItemType::Display);
args.name(menuFunction.object());
eci.parmPackedArgs(args);
eci.parmAlertBuffer(record);
eci.parmAlertFormDsName(dataSourceName);
//eci.parmDontUseFormRunFromMenuItem(true);
inboxData.InboxId = inboxId;
inboxData.DataType = EventInboxDataType::Context;
inboxData.Data = eci.pack();
inboxData.insert();
inbox.AlertTableId = table.id();
inbox.ParentTableId = table.id();
recordCaptionGenerator = WorkflowRecordCaptionGenerator::construct(record);
inbox.AlertedFor = recordCaptionGenerator.caption();
list = SysDictTable::getUniqueIndexFields(table.id());
if (list)
{
inbox.keyFieldList(list.pack());
inbox.keyFieldData(SysDictTable::mapFieldIds2Values(list,record).pack());
}
inbox.CompanyId = record.company();
}
inbox.insert();
}

使用上面的函数来创建Alert:

static void Job155(Args _args)
{
InventTable inventTable;
select firstOnly inventTable;
DEVUtils::CreateAlert("message", "subject", curUserId(), true, false, inventTable, "InventTable", new MenuFunction(menuitemDisplayStr(EcoResProductDetailsExtended), MenuItemType::Display));
}

上面的CreateAlert函数有个sendEmail参数,对应EventInbox的字段SendEmail,把这个参数设置为true,我们也不会收到邮件,因为我们只是标记了这个字段,我没有找到系统中有比如batch job来将EventInbox通过邮件发送出去。

[AX2012 R3]关于Alerts的更多相关文章

  1. AX2012 R3升级CU8的一些错误

    AX2012 R3安装升级包CU8后进入系统,系统会提示打开软件升级清单“Software update checklist”,清单列出了升级要做的一系列动作. 在进行到编译应用时“Compile a ...

  2. AX2012 R3 Data upgrade checklist sync database step, failed to create a session;

    最近在做AX2012 R3 CU9 到CU11的upgrade时 (用的Admin帐号), 在Date upgrade 的 synchronize database 这步 跑了一半,报出错误 说“fa ...

  3. [AX2012 R3]在SSRS报表中使用QR二维码

    AX2012是自带生成QR二维码的类,可以很方便的用在SSRS报表中,下面演示如何在RDP的报表中使用二维码,首先从定义临时表开始: 字段URL是要用于二维码的字符串,QrCode是container ...

  4. [AX2012 R3]关于Named user license report

    Named user license报表是用来统计各种授权类型用户数的,这里来看看报表数据具体是如何来的.这是一个SSRS的报表,最主要的数据源是来自于类SysUserLicenseCountRepo ...

  5. How to Operate SharePoint User Alerts with PowerShell

    When you migrate list or site, the user alerts in the site will not be migrated together with the co ...

  6. Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBoxDD): GetLastError=1790 (VERR_UNRESOLVED_ERROR).

    Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBoxDD): GetLastError=1790 ( ...

  7. Dynamics AX 2012 R3 仓库和运输管理系列 - 仓库管理模块安装与配置

        在AX 2012 R3版本中,新增了仓库和运输管理模块,同时提供了一个在移动设备上进行仓库管理工作的网站.在这个系列里,与Reinhard一起,了解仓库和运输管理模块吧.     需要注意的是 ...

  8. Bootstrap <基础二十五>警告(Alerts)

    警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...

  9. AX2012导Demo数据

    看到这篇文章后http://www.cnblogs.com/duanshuiliu/archive/2012/07/18/2597645.html,为了大家的方便就分享下 关于AX2012的导Demo ...

随机推荐

  1. Swift闭包概念与常见使用场景总结

    ·Swift 闭包 闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些 ...

  2. Jeasyframe 开源框架 稳定版 V1.5 发布

    这是Jeasyframe开源框架的第一个稳定版本,感谢一起帮忙测试并给予反馈的网友们. 框架官网:http://www.jeasyframe.org/ 产品介绍: Jeasyframe开源框架是基于S ...

  3. Spring Mobile 1.1.0.RC1 和 1.0.2 发布

    Spring Mobile 1.1.0.RC1 发布了,该版本包含: 支持 Firefox OS 设备的检测 修复了使用 LiteDeviceDelegatingViewResolver 处理重定向和 ...

  4. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块

    本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...

  5. xps 文件操作笔记

    1. 在 Silverlight 显示XPS文件,参考:http://azharthegreat.codeplex.com/ 2. Word,Excel, PPT 文件转换为XPS: 参考一(老外写的 ...

  6. C#函数式编程之标准高阶函数

    何为高阶函数 大家可能对这个名词并不熟悉,但是这个名词所表达的事物却是我们经常使用到的.只要我们的函数的参数能够接收函数,或者函数能够返回函数,当然动态生成的也包括在内.那么我们就将这类函数叫做高阶函 ...

  7. angular-ui-bootstrap的进度条问题及解决

    在测试angular-ui-bootstrap中的进度条的时候,用的是官方的示例代码,但是跑不起来. 经过代码比对之后,发现官方用的是0.14.3, 而我本地用的是0.13.3 (2015-08-09 ...

  8. jQuery的XX如何实现?——4.类型检查

    往期回顾: jQuery的XX如何实现?——1.框架 jQuery的XX如何实现?——2.show与链式调用 jQuery的XX如何实现?——3.data与cache机制 -------------- ...

  9. Spring 之autowired

    Spring中autowired主要用于装配树形值,其关键类为BeanWrapperImpl,阅读代码发现其关键方法setPropertyValue有如下一段代码. PropertyHandler p ...

  10. Maven之问题解决汇总

    Maven使用中,遇到的问题及解决办法记录下来 pom.xml顶部报错问题解决方法:http://stackoverflow.com/questions/5074063/maven-error-fai ...