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. Makecert.exe(证书创建工具)

    Makecert.exe(证书创建工具) .NET Framework 4.5   其他版本   2(共 3)对本文的评价是有帮助 - 评价此主题   证书创建工具生成仅用于测试目的的 X.509 证 ...

  2. LoadTest内存和线程Troubleshooting实战

    在端午节放假的三天中,我对正在开发的 Service 进行了 LoadTest,尝试在增大压力的条件下发现问题. 该 Service 为独立进程的 WCF 服务,宿主于 WindowsService, ...

  3. 关于消除if-else的简单总结

    if-else是计算机语言中基本的分支语句,虽然很简单,但可能会出现滥用的情况,如图: 这种标记判断,嵌套成这样(其实没有必要嵌套),会让别人觉得作者水平很低. 可以看出,这些if仅仅是在判断一个变量 ...

  4. spring mvc ajax 400解决

    The request sent by the client was syntactically incorrect. ajax发起请求时报400错误.请求代码如下: var reportId=($( ...

  5. Nhibernate基础使用教程以及简易封装

    1.Nhibernate简介 NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技 ...

  6. Facebook网络模拟测试工具ATC使用

    Facebook在其工程博客(原文)上宣布开源移动网络测试工具Augmented Traffic Control(ATC),我迅速试用了一番,非常不错,对手游或者其他APP的调试和测试都非常有帮助,介 ...

  7. MySql查询数据库的大小

    第一步:首先打开Mysql命令行,通过开始菜单-程序-MySql-Command line client,如图1-1所示: 图1-1 第二步:在命令中输入use information_schema ...

  8. Atitit.列表页面and条件查询的实现最佳实践(2)------翻页 分页 控件的实现java .net php

    )------翻页 分页 控件的实现java .net php 1. 关于翻页有关的几大控件::搜索框控件,显示表格控件,翻页器,数据源控件.. 1 2. 翻页的显示格式:: 1 2.1. 通常ui- ...

  9. 盘点mysql中容易被我们误会的地方

    引语:mysql作为数据库的一大主力军,到处存在于我们各种系统中,相信大家都不陌生!但是,你知道你能用不代表你知道细节,那我们就来盘点盘点其中一些我们平时不太注意的地方,一来为了有趣,二来为了不让自己 ...

  10. iOS---性能优化

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧.小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...