Skip to main content

Email alerts after management report

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();
    }

}

Comments

Popular posts from this blog

Number sequence with existing module and new module

Number sequence customization in Dynamics 365 Create a number sequence in a standard module Step 1: Create new EDT Step 2: Add a new code block to the loadModule in the NumberSeqModuleXXX class Step 3: Add a new static method to the parameters table of the module to get the number sequence reference Using Extension [ExtensionOf(classStr(NumberSeqModuleCustomer))] final class NumberSeqModuleCustTest_Extension { protected void loadModule() { NumberSeqDatatype datatype = NumberSeqDatatype::construct(); next loadModule(); datatype.parmDatatypeId(extendedTypeNum(TestId)); datatype.parmReferenceHelp(literalStr(‘Test ID’)); datatype.parmWizardIsContinuous(false); datatype.parmWizardIsManual(NoYes::No); datatype.parmWizardIsChangeDownAllowed(NoYes::No); datatype.parmWizardIsChangeUpAllowed(NoYes::No); datatype.parmSortField(1); datatype.addParameterType(NumberSeqParameterType::DataArea, true, false); this.create(datatype); } } [ExtensionOf(tableStr(CustParameters...

[D365/AX7] How to: Create and Use number sequence

[D365/AX7] How to: Create number sequence Posted on January 7, 2018 Updated on January 11, 2018 Number sequences are used to generate readable, unique identifiers for master data records and transaction records that require identifiers. A master data record or transaction record that requires an identifier is referred to as a reference. On this example, we are going to create a new number sequence for customer group. Create a new class that extends the NumberSeqModuleCustomer class and then create the method loadModule_Extension and add the following code: class NumberSeqModuleCustomer_CFS extends NumberSeqModuleCustomer {         public void loadModule_Extension()         {                 NumberSeqDatatype datatype = NumberSeqDatatype::construct();          ...

Batch Multi threading D365FO AX7

Batch Multi threading D365FO AX7 Normally, when we schedule our RunBaseBatch class as a batch job, it will create single task. Which will responsible to execute complete process in single thread. But, As you know like AX-2009 and AX-2012. In D365FO We can add multiple AOS server in single batch group and they can process the multiple task simultaneously.  In this demo I will show, How to create multi threading Batch job. following are the steps Step-1 Create a table for demo purpose in our demo we keep table name is  SLD_DemoTable . Step-2 create a class with name  SLD_DemoBusinessLogic  and write your business logic in this class. In demo I write only insert records in table and show you guys how it works. Reference Code class   SLD_DemoBusinessLogic {      public   void  processInit( VendTable  _vend)     {          SLD_DemoTable  ...