Wednesday, July 24, 2024

D365 Sending Email with Customer Account Statement SSRS report as attachment using X++

D365 Sending Email with Customer Account Statement SSRS report as attachment using X++




 custTable _custTable;
              

                SysOperationQueryDataContractInfo sysOperationQueryDataContractInfo;
                SrsReportRunController reportRunController;
                CustTransListContract custTransListContract;
                SRSReportExecutionInfo reportExecutionInfo;
                SRSPrintDestinationSettings printDestinationSettings;
                SRSReportRunService srsReportRunService;
                SRSProxy srsProxy;
                QueryBuildRange qbrCustAccount;
                QueryBuildDataSource queryBuildDataSource;
                Object dataContractInfoObject;
                Map reportParametersMap;
                Map mapCustAccount;
                MapEnumerator mapEnumerator;
                Array arrayFiles;
                System.Byte[] reportBytes;
                Filename fileName;
                Args args;
                System.IO.MemoryStream memoryStream;
                System.IO.MemoryStream fileStream;
                CustParameters custParameters;
                Email toEmail;


                Map                                 templateTokens;
                str                                 emailSenderName;
                str                                 emailSenderAddr;
                str                                 emailSubject;
                str                                 emailBody;
 
                Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;
 
                #define.Subject("Subject")
                #define.CustAccount("CustAccount")
                #define.EmailDate("Date");
 
                custParameters          = CustParameters::find();
 
                reportRunController     = new SrsReportRunController();
                custTransListContract   = new CustTransListContract();
                reportExecutionInfo     = new SRSReportExecutionInfo();
                srsReportRunService     = new SrsReportRunService();
                reportBytes             = new System.Byte[0]();
                args                    = new Args();
                templateTokens          = new Map(Types::String, Types::String);
                var messageBuilder      = new SysMailerMessageBuilder();
 
                // custTransListContract.parmNewPage(NoYes::Yes);
                str custAccount = "10000";
                _custTable = CustTable::find(custAccount);
                if(!_custTable)
                {
                    return "No Customer found";
                }
                if(!emailAddress)
                {
                    return "No emailAddress";
                }
                fileName    = strFmt("CustomerAccountStatement_%1.pdf", _custTable.AccountNum);
 
                reportRunController.parmArgs(args);
                reportRunController.parmReportName(ssrsReportStr(CustTransList, Report));
                reportRunController.parmShowDialog(false);
                reportRunController.parmLoadFromSysLastValue(false);
                reportRunController.parmReportContract().parmRdpContract(custTransListContract);
 
                // Modify query
                mapCustAccount = reportRunController.getDataContractInfoObjects();
                mapEnumerator = mapCustAccount.getEnumerator();
 
                while (mapEnumerator.moveNext())
                {
                    dataContractInfoObject = mapEnumerator.currentValue();
 
                    if (dataContractInfoObject is SysOperationQueryDataContractInfo)
                    {
                        sysOperationQueryDataContractInfo = dataContractInfoObject;
 
                        queryBuildDataSource    = SysQuery::findOrCreateDataSource(sysOperationQueryDataContractInfo.parmQuery()
                                                                    , tableNum(CustTable));
                        qbrCustAccount          = SysQuery::findOrCreateRange(queryBuildDataSource, fieldNum(CustTable, AccountNum));
                        qbrCustAccount.value(_custTable.AccountNum);
                    }
                }
 
                printDestinationSettings = reportRunController.parmReportContract().parmPrintSettings();
                printDestinationSettings.printMediumType(SRSPrintMediumType::File);
                printDestinationSettings.fileName(fileName);
                printDestinationSettings.fileFormat(SRSReportFileFormat::PDF);
 
                reportRunController.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
                reportRunController.parmReportContract().parmReportExecutionInfo(reportExecutionInfo);
 
                srsReportRunService.getReportDataContract(reportRunController.parmreportcontract().parmReportName());
                srsReportRunService.preRunReport(reportRunController.parmreportcontract());
 
                reportParametersMap = srsReportRunService.createParamMapFromContract(reportRunController.parmReportContract());
                parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);
 
                srsProxy        = SRSProxy::constructWithConfiguration(reportRunController.parmReportContract().parmReportServerConfig());
                reportBytes     = srsproxy.renderReportToByteArray(reportRunController.parmreportcontract().parmreportpath()
                                                    , parameterValueArray
                                                    , printDestinationSettings.fileFormat()
                                                    , printDestinationSettings.deviceinfo());
 
                memoryStream    = new System.IO.MemoryStream(reportBytes);
                memoryStream.Position = 0;
 
                fileStream      = memoryStream;
                toEmail         =  this.getCustEmail(_custTable.AccountNum);
 
      

                    emailBody = "Dear Customr, Please find attached Customer account statement till today.";
                    emailSubject = strFmt("Customer account statement for %1", _custTable.AccountNum);
                    emailSenderAddr = "msd@test.com";
                    emailSenderName = strFmt("Customer account statement for %1", _custTable.AccountNum);


                    messageBuilder.addTo(toEmail)
                        .setSubject(emailSubject)
                        .setBody(SysEmailMessage::stringExpand(emailBody, SysEmailTable::htmlEncodeParameters(templateTokens))).addCC("");
 
                 
                    messageBuilder.setFrom(emailSenderAddr , emailSenderName );
           
                    messageBuilder.addAttachment(fileStream, fileName);
 
                    SysMailerFactory::sendNonInteractive(messageBuilder.getMessage());



public Email getCustEmail(CustAccount _custAccount)
{
    CustTable                   custTable;
    DirPartyLocation            dirPartyLocation;
    LogisticsLocation           logisticsLocation;
    LogisticsElectronicAddress  logisticsElectronicAddress;
 
    custTable = CustTable::find(_custAccount);
 
    select firstonly Location, Party from dirPartyLocation
        where dirPartyLocation.Party                        == custTable.Party
            join RecId from logisticsLocation
                where logisticsLocation.RecId               == dirPartyLocation.Location
            join Locator from logisticsElectronicAddress
                where logisticsElectronicAddress.Location   == logisticsLocation.RecId
                    && logisticsElectronicAddress.Type      == LogisticsElectronicAddressMethodType::Email
                    && logisticsElectronicAddress.IsPrimary == NoYes::Yes;
 
    return logisticsElectronicAddress.Locator;
}

Tuesday, July 23, 2024

clicking link on info message X++ to Open form

 Message::AddAction() method can be used to embed an action within a message sent to the message bar. This method supports adding a single action that is associated with a display or action menu item, which is then visualized as a link button, redirecting users directly to the form with the correct record selected. Here's how it can be used.



public static void pushNotification(str  NotificationMsg, str actionText,LedgerJournalTable journalTable)
{
    MenuItemMessageAction actionData = new MenuItemMessageAction();
    actionData.MenuItemName(menuItemDisplayStr(LedgerJournalTable));
    actionData.TableName(tableStr(LedgerJournalTable));
    actionData.RecId(journalTable.RecId);
    
    str jsonData = FormJsonSerializer::serializeClass(actionData);
 
    int64 messageId = Message::AddAction(MessageSeverity::Informational,NotificationMsg ,actionText, MessageActionType::DisplayMenuItem, jsonData);
} 

Muhammad Aamir Hanif Reference