Loading...

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++
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);
        
                _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 = "[email protected]";
                    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;
}

Published on:

Learn more
Sherif Fayed
Sherif Fayed

Share post:

Related posts

Build an X++ AI Tool for Copilot Studio in Dynamics 365 F&O

Learn how to wire real F&O business logic into Copilot Studio. This guide shows you how to build an X++ AI tool, set up security, auto/ha...

5 days ago

Microsoft Dataverse – Copilot support for finance and operations development

We are announcing Copilot support for finance and operations development in Microsoft Dataverse. This feature will reach general availability ...

10 days ago

Copilot Studio 101: Extend Dynamics 365 F&O Copilots

Kick off a hands-on series on Copilot Studio for Dynamics 365 F&O. See what it is, the setup you need, how it uses Dataverse, built-in co...

12 days ago

New Feature in Dynamics 365 F&O 10.0.45 Preview: Customer Invoice Logging and Traceability Framework

Have you been posting Sales Order Invoices and Customer Free Text Invoices through batch jobs, only to struggle with tracking the status of th...

1 month ago

Part-10: Create your Custom Agent for D365 F&O[Chart of Account Agent]

Enough talk. Let’s see Copilot Studio in action. Over the weekend, I built something powerful – a custom AI agent for Microsoft Dynamics 365 F...

1 month ago

New Approved Customer List mapping for Items in Dynamics 365 Finance and operations

Take control of your sales process with the latest feature in Microsoft Dynamics 365 Finance – the Approved Customer List! This powerful new f...

1 month ago

Part-9: Connect and Query Dynamics 365 Finance and operations data with Copilot studio

In this video, we kick off an exciting new series focused on extending Copilot Studio capabilities by connecting it to real enterprise data! �...

1 month ago

How to Create Deep Links to D365 F&O Records with Dataverse Virtual Tables

It is a common requirement for SaaS platform that exposes form over data to be able to share a secure link (a.k.a. Deep Link) to access a give...

4 months ago

Simplifying License Management for Dynamics 365 Finance and Operations: Improved User License Validation

Starting April 30th, Dynamics 365 administrators will gain access to new license usage reporting tools, centralizing user license management. ...

5 months ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy