Email alerts after management report
//In GeneralLedgerParameters - created new table for emailsetup template for reportname and assign grid in this form
Fields = REportname,usergroup,Emailtemplate.
//Email template available in Organization administration
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
</head>
<body>
Hi,<br>
<br>
%ReportName% report has been generated on %GeneratedDate% by %GeneratedBy%.<br>
<br>
Please find the below link to access the report.<br>
<a href="%ReportUrl%">%ReportName%</a>
<br>
<br>
</body>
</html>
//Added new field in FinancialReportversion-Emailflag
class DFRG_EmailAlerts
{
public static void main(Args _args)
{
FinancialReportVersion financialReportVersion, financialReportVersionLocal;
int totalRecords;
DataAreaId dataAreaId;
select count(RecId) from financialReportVersion where financialReportVersion.DFRG_Emailalert == NoYes::No;
totalRecords = financialReportVersion.RecId;
//while select crosscompany dataAreaId from financialReportVersion group by DataAreaId
//{
// dataAreaId = financialReportVersion.DataAreaId;
// changecompany(dataAreaId)
// {
// update_recordset financialReportVersionLocal setting DFRG_Emailalert = NoYes::Yes;
// }
//}
update_recordset financialReportVersionLocal setting DFRG_Emailalert = NoYes::Yes;
info(strFmt("%1 records has been updated.", totalRecords));
}
}
//Creating new record from UI-FinancialReports form
class DFRG_FinancialReportVersionEventHandler
{
/// <summary>
/// Send an email notification on new financial report creation.
/// </summary>
/// <param name="sender">Sender.</param>
/// <param name="e">Data event args.</param>
[DataEventHandler(tableStr(FinancialReportVersion), DataEventType::Inserted)]
public static void FinancialReportVersion_onInserted(Common sender, DataEventArgs e)
{
FinancialReportVersion financialReportVersion = sender as FinancialReportVersion;
financialReportVersion financialReportVersionLocal;
//updateing the DFRG_Emailalert to yes, when creating by UI
select forupdate financialReportVersionLocal where financialReportVersionLocal.RecId == financialReportVersion.RecId;
ttsbegin;
financialReportVersionLocal.DFRG_Emailalert = NoYes::Yes;
financialReportVersionLocal.doUpdate();
ttscommit;
}
}
//Creating URL link based on extension of URLUtility class
using Microsoft.Dynamics.AX.Framework.Utilities;
using Microsoft.Dynamics.@Client.ServerForm.Contexts;
using Microsoft.Dynamics.ApplicationPlatform.Environment;//Added for Environment frame
/// <summary>
/// The class <c>URLUtility_Extension</c> contains extension methods for the <c>URLUtility</c> class.
/// </summary>
[ExtensionOf(classStr(URLUtility))]
public static class DFRG_URLUtility_Extension
{
public static str generateRecordUrl(str _menuItemName, MenuItemType _menuItemType, DataSourceName _dataSourceName, Map _indexFieldValuesMap, DataAreaId _dataAreaId = curExt())
{
System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
generator.MenuItemName = _menuItemName;
generator.MenuItemType = _menuItemType;
generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
generator.Company = _dataAreaId;
generator.EncryptRequestQuery = true;
if (_dataSourceName && _indexFieldValuesMap)
{
MapEnumerator mapEnumerator = _indexFieldValuesMap.getEnumerator();
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
while (mapEnumerator.moveNext())
{
requestQueryParameterCollection.UpdateOrAddEntry(_dataSourceName, mapEnumerator.currentKey(), mapEnumerator.currentValue());
}
}
return generator.GenerateFullUrl().AbsoluteUri;
}
/// <summary>
/// This Method for generate URL using _formDataSource
/// </summary>
/// <param name = "_formDataSource"></param>
/// <returns></returns>
public static str generateRecordUrlFromDataSource(FormDataSource _formDataSource)
{
FormRun formRun = _formDataSource.formRun();
str menuItemName = formRun.args().menuItemName();
MenuItemType menuItemType = formRun.args().menuItemType();
DataSourceName dataSourceName = _formDataSource.name();
TableId tableId = _formDataSource.table();
DictTable dictTable = new DictTable(tableId);
DictIndex dictIndex = new DictIndex(tableId, dictTable.primaryIndex());
int fieldCount = dictIndex.numberOfFields();
Map indexFieldValuesMap = new Map(Types::String, Types::String);
Common record = _formDataSource.cursor();
FieldId primaryKeyFieldId;
for (int fieldIndex = 1; fieldIndex <= fieldCount; fieldIndex++)
{
primaryKeyFieldId = dictIndex.field(fieldIndex);
indexFieldValuesMap.insert(fieldId2Name(tableId, primaryKeyFieldId), any2Str(record.(primaryKeyFieldId)));
}
return URLUtility::generateRecordUrl(menuItemName, menuItemType, dataSourceName, indexFieldValuesMap, record.DataAreaId);
}
//vinod-deep links in batch process in Dynamics 365 for Finance and Operations
public static str generateRecordUrlDesign(str _menuItemName, MenuItemType _menuItemType, DataSourceName _dataSourceName, FinancialReportDesignId _designId, DataAreaId _dataAreaId = curExt())
{
//line of code doesn’t work in batch process, because the SessionContext object instance is null when running in batch:
//System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
//The workaround is to use EnvironmentFactory::GetApplicationEnvironment() method instead, in order to read its Infrastructure.HostUrl:
IApplicationEnvironment env = EnvironmentFactory::GetApplicationEnvironment();
str currentUrl = env.Infrastructure.HostUrl;
System.Uri host = new System.Uri(currentUrl);
UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
generator.MenuItemName = _menuItemName;
generator.MenuItemType = _menuItemType;
generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
generator.Company = _dataAreaId;
generator.EncryptRequestQuery = true;
generator.Partition = getCurrentPartition();
Map indexFieldValuesMap;
indexFieldValuesMap = new Map(Types::String,Types::String);
indexFieldValuesMap.insert(fieldStr(FinancialReports, DesignId),strFmt("%1",_designId));
if (_dataSourceName && indexFieldValuesMap)
{
MapEnumerator mapEnumerator = indexFieldValuesMap.getEnumerator();
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
while (mapEnumerator.moveNext())
{
requestQueryParameterCollection.UpdateOrAddEntry(_dataSourceName, mapEnumerator.currentKey(), mapEnumerator.currentValue());
}
}
return generator.GenerateFullUrl().AbsoluteUri;
}
}
//Service of Batch job process
Public class DFRG_EmailAlertsBatchjob extends SysOperationServiceBase
{
Public void processOperation()
{
FinancialReportVersion financialReportVersion,financialReportVersionLocal;
DFRG_FinancialEmail financialEmail;
//Nowsath
SysMailerMessageBuilder MessageBuilder;
SysEmailTable sysEmailTable;
SysEmailMessageTable message;
Map mappings, indexFieldValuesMap, designId;
UserGroupList userGroupList;
UserInfo userInfo;
DFRG_FinancialReportEmailSetupTable FinancialReportEmailSetupTable;
FinancialReports financialReports;
str ReportUrl;
//Nowsath
while select financialReportVersion where financialReportVersion.DFRG_Emailalert == NoYes::No
{
select firstonly ReportName from financialReports
where financialReports.DesignId == financialReportVersion.DesignId;
select FinancialReportEmailSetupTable
where FinancialReportEmailSetupTable.ReportName == financialReports.ReportName;
if(FinancialReportEmailSetupTable.ReportName)
{
sysEmailTable = SysEmailTable::find(FinancialReportEmailSetupTable.EmailId);
message = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);
mappings = new Map(Types::String, Types::String);
ReportUrl = "";
ReportUrl = URLUtility::generateRecordUrlDesign(menuItemDisplayStr(FinancialReports), MenuItemType::Display, identifierStr(FinancialReports), financialReportVersion.DesignId);
try
{
while select UserId from userGroupList
where userGroupList.groupId == FinancialReportEmailSetupTable.UserGroupId
join NetworkAlias from userInfo
where userInfo.id == userGroupList.userId
{
MessageBuilder = new SysMailerMessageBuilder();
mappings.insert("Reportname", financialreports.ReportName);
mappings.insert("GeneratedDate", strFmt("%1", financialReportVersion.GeneratedDate));
mappings.insert("GeneratedBy", financialReportVersion.GeneratedBy);
mappings.insert("ReportUrl", strFmt("%1", ReportUrl, financialReports.ReportName));
MessageBuilder.setSubject(message.Subject);
MessageBuilder.setFrom(sysEmailTable.SenderAddr);
MessageBuilder.addTo(UserInfo.networkAlias);
MessageBuilder.setBody(SysEmailMessage::stringExpand(message.Mail, mappings));
SysMailerFactory::sendNonInteractive(MessageBuilder.getMessage());
//vinod
//update financialreportversion table with DFRG_Emailalert to yes
select forupdate financialReportVersionLocal where financialReportVersionLocal.RecId == financialReportVersion.RecId;
ttsbegin;
financialReportVersionLocal.DFRG_Emailalert = NoYes::Yes;
financialReportVersionLocal.doUpdate();
ttscommit;
info(strFmt("Successfully generated email for reportid: %1",financialReportVersionLocal.ReportId));
//Inserting records in customizied table
financialEmail.ReportId = financialReportVersion.ReportId;
financialEmail.Emailflag = NoYes::Yes;
financialEmail.insert();
//vinod
}
}
catch(Exception::Error)
{
throw warning('@DFRG:DFRGMailAlert02');
}
catch(Exception::CLRError)
{
error(CLRInterop::getLastException().toString());
}
}
info(strfmt("%1", xGlobal::clientKind()));
}
}
}
//Batchjob controller class
class DFRG_EmailAlertsBatchjobController extends SysOperationServiceController
{
public void new()
{
super(classStr(DFRG_EmailAlertsBatchjob),methodStr(DFRG_EmailAlertsBatchjob, processOperation),SysOperationExecutionMode::Synchronous);
}
public ClassDescription caption()
{
return "Financial report email batch.";
}
public static void main(Args args)
{
DFRG_EmailAlertsBatchjobController controller;
controller = new DFRG_EmailAlertsBatchjobController();
controller.startOperation();
}
}
//In GeneralLedgerParameters - created new table for emailsetup template for reportname and assign grid in this form
Fields = REportname,usergroup,Emailtemplate.
//Email template available in Organization administration
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
</head>
<body>
Hi,<br>
<br>
%ReportName% report has been generated on %GeneratedDate% by %GeneratedBy%.<br>
<br>
Please find the below link to access the report.<br>
<a href="%ReportUrl%">%ReportName%</a>
<br>
<br>
</body>
</html>
//Added new field in FinancialReportversion-Emailflag
class DFRG_EmailAlerts
{
public static void main(Args _args)
{
FinancialReportVersion financialReportVersion, financialReportVersionLocal;
int totalRecords;
DataAreaId dataAreaId;
select count(RecId) from financialReportVersion where financialReportVersion.DFRG_Emailalert == NoYes::No;
totalRecords = financialReportVersion.RecId;
//while select crosscompany dataAreaId from financialReportVersion group by DataAreaId
//{
// dataAreaId = financialReportVersion.DataAreaId;
// changecompany(dataAreaId)
// {
// update_recordset financialReportVersionLocal setting DFRG_Emailalert = NoYes::Yes;
// }
//}
update_recordset financialReportVersionLocal setting DFRG_Emailalert = NoYes::Yes;
info(strFmt("%1 records has been updated.", totalRecords));
}
}
//Creating new record from UI-FinancialReports form
class DFRG_FinancialReportVersionEventHandler
{
/// <summary>
/// Send an email notification on new financial report creation.
/// </summary>
/// <param name="sender">Sender.</param>
/// <param name="e">Data event args.</param>
[DataEventHandler(tableStr(FinancialReportVersion), DataEventType::Inserted)]
public static void FinancialReportVersion_onInserted(Common sender, DataEventArgs e)
{
FinancialReportVersion financialReportVersion = sender as FinancialReportVersion;
financialReportVersion financialReportVersionLocal;
//updateing the DFRG_Emailalert to yes, when creating by UI
select forupdate financialReportVersionLocal where financialReportVersionLocal.RecId == financialReportVersion.RecId;
ttsbegin;
financialReportVersionLocal.DFRG_Emailalert = NoYes::Yes;
financialReportVersionLocal.doUpdate();
ttscommit;
}
}
//Creating URL link based on extension of URLUtility class
using Microsoft.Dynamics.AX.Framework.Utilities;
using Microsoft.Dynamics.@Client.ServerForm.Contexts;
using Microsoft.Dynamics.ApplicationPlatform.Environment;//Added for Environment frame
/// <summary>
/// The class <c>URLUtility_Extension</c> contains extension methods for the <c>URLUtility</c> class.
/// </summary>
[ExtensionOf(classStr(URLUtility))]
public static class DFRG_URLUtility_Extension
{
public static str generateRecordUrl(str _menuItemName, MenuItemType _menuItemType, DataSourceName _dataSourceName, Map _indexFieldValuesMap, DataAreaId _dataAreaId = curExt())
{
System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
generator.MenuItemName = _menuItemName;
generator.MenuItemType = _menuItemType;
generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
generator.Company = _dataAreaId;
generator.EncryptRequestQuery = true;
if (_dataSourceName && _indexFieldValuesMap)
{
MapEnumerator mapEnumerator = _indexFieldValuesMap.getEnumerator();
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
while (mapEnumerator.moveNext())
{
requestQueryParameterCollection.UpdateOrAddEntry(_dataSourceName, mapEnumerator.currentKey(), mapEnumerator.currentValue());
}
}
return generator.GenerateFullUrl().AbsoluteUri;
}
/// <summary>
/// This Method for generate URL using _formDataSource
/// </summary>
/// <param name = "_formDataSource"></param>
/// <returns></returns>
public static str generateRecordUrlFromDataSource(FormDataSource _formDataSource)
{
FormRun formRun = _formDataSource.formRun();
str menuItemName = formRun.args().menuItemName();
MenuItemType menuItemType = formRun.args().menuItemType();
DataSourceName dataSourceName = _formDataSource.name();
TableId tableId = _formDataSource.table();
DictTable dictTable = new DictTable(tableId);
DictIndex dictIndex = new DictIndex(tableId, dictTable.primaryIndex());
int fieldCount = dictIndex.numberOfFields();
Map indexFieldValuesMap = new Map(Types::String, Types::String);
Common record = _formDataSource.cursor();
FieldId primaryKeyFieldId;
for (int fieldIndex = 1; fieldIndex <= fieldCount; fieldIndex++)
{
primaryKeyFieldId = dictIndex.field(fieldIndex);
indexFieldValuesMap.insert(fieldId2Name(tableId, primaryKeyFieldId), any2Str(record.(primaryKeyFieldId)));
}
return URLUtility::generateRecordUrl(menuItemName, menuItemType, dataSourceName, indexFieldValuesMap, record.DataAreaId);
}
//vinod-deep links in batch process in Dynamics 365 for Finance and Operations
public static str generateRecordUrlDesign(str _menuItemName, MenuItemType _menuItemType, DataSourceName _dataSourceName, FinancialReportDesignId _designId, DataAreaId _dataAreaId = curExt())
{
//line of code doesn’t work in batch process, because the SessionContext object instance is null when running in batch:
//System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
//The workaround is to use EnvironmentFactory::GetApplicationEnvironment() method instead, in order to read its Infrastructure.HostUrl:
IApplicationEnvironment env = EnvironmentFactory::GetApplicationEnvironment();
str currentUrl = env.Infrastructure.HostUrl;
System.Uri host = new System.Uri(currentUrl);
UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
generator.MenuItemName = _menuItemName;
generator.MenuItemType = _menuItemType;
generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
generator.Company = _dataAreaId;
generator.EncryptRequestQuery = true;
generator.Partition = getCurrentPartition();
Map indexFieldValuesMap;
indexFieldValuesMap = new Map(Types::String,Types::String);
indexFieldValuesMap.insert(fieldStr(FinancialReports, DesignId),strFmt("%1",_designId));
if (_dataSourceName && indexFieldValuesMap)
{
MapEnumerator mapEnumerator = indexFieldValuesMap.getEnumerator();
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
while (mapEnumerator.moveNext())
{
requestQueryParameterCollection.UpdateOrAddEntry(_dataSourceName, mapEnumerator.currentKey(), mapEnumerator.currentValue());
}
}
return generator.GenerateFullUrl().AbsoluteUri;
}
}
//Service of Batch job process
Public class DFRG_EmailAlertsBatchjob extends SysOperationServiceBase
{
Public void processOperation()
{
FinancialReportVersion financialReportVersion,financialReportVersionLocal;
DFRG_FinancialEmail financialEmail;
//Nowsath
SysMailerMessageBuilder MessageBuilder;
SysEmailTable sysEmailTable;
SysEmailMessageTable message;
Map mappings, indexFieldValuesMap, designId;
UserGroupList userGroupList;
UserInfo userInfo;
DFRG_FinancialReportEmailSetupTable FinancialReportEmailSetupTable;
FinancialReports financialReports;
str ReportUrl;
//Nowsath
while select financialReportVersion where financialReportVersion.DFRG_Emailalert == NoYes::No
{
select firstonly ReportName from financialReports
where financialReports.DesignId == financialReportVersion.DesignId;
select FinancialReportEmailSetupTable
where FinancialReportEmailSetupTable.ReportName == financialReports.ReportName;
if(FinancialReportEmailSetupTable.ReportName)
{
sysEmailTable = SysEmailTable::find(FinancialReportEmailSetupTable.EmailId);
message = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);
mappings = new Map(Types::String, Types::String);
ReportUrl = "";
ReportUrl = URLUtility::generateRecordUrlDesign(menuItemDisplayStr(FinancialReports), MenuItemType::Display, identifierStr(FinancialReports), financialReportVersion.DesignId);
try
{
while select UserId from userGroupList
where userGroupList.groupId == FinancialReportEmailSetupTable.UserGroupId
join NetworkAlias from userInfo
where userInfo.id == userGroupList.userId
{
MessageBuilder = new SysMailerMessageBuilder();
mappings.insert("Reportname", financialreports.ReportName);
mappings.insert("GeneratedDate", strFmt("%1", financialReportVersion.GeneratedDate));
mappings.insert("GeneratedBy", financialReportVersion.GeneratedBy);
mappings.insert("ReportUrl", strFmt("%1", ReportUrl, financialReports.ReportName));
MessageBuilder.setSubject(message.Subject);
MessageBuilder.setFrom(sysEmailTable.SenderAddr);
MessageBuilder.addTo(UserInfo.networkAlias);
MessageBuilder.setBody(SysEmailMessage::stringExpand(message.Mail, mappings));
SysMailerFactory::sendNonInteractive(MessageBuilder.getMessage());
//vinod
//update financialreportversion table with DFRG_Emailalert to yes
select forupdate financialReportVersionLocal where financialReportVersionLocal.RecId == financialReportVersion.RecId;
ttsbegin;
financialReportVersionLocal.DFRG_Emailalert = NoYes::Yes;
financialReportVersionLocal.doUpdate();
ttscommit;
info(strFmt("Successfully generated email for reportid: %1",financialReportVersionLocal.ReportId));
//Inserting records in customizied table
financialEmail.ReportId = financialReportVersion.ReportId;
financialEmail.Emailflag = NoYes::Yes;
financialEmail.insert();
//vinod
}
}
catch(Exception::Error)
{
throw warning('@DFRG:DFRGMailAlert02');
}
catch(Exception::CLRError)
{
error(CLRInterop::getLastException().toString());
}
}
info(strfmt("%1", xGlobal::clientKind()));
}
}
}
//Batchjob controller class
class DFRG_EmailAlertsBatchjobController extends SysOperationServiceController
{
public void new()
{
super(classStr(DFRG_EmailAlertsBatchjob),methodStr(DFRG_EmailAlertsBatchjob, processOperation),SysOperationExecutionMode::Synchronous);
}
public ClassDescription caption()
{
return "Financial report email batch.";
}
public static void main(Args args)
{
DFRG_EmailAlertsBatchjobController controller;
controller = new DFRG_EmailAlertsBatchjobController();
controller.startOperation();
}
}
Comments
Post a Comment