Showing posts with label Azure. Show all posts
Showing posts with label Azure. Show all posts

Email SSRS Report As Attachment D365FO


SSRS Report Email Attachment Dynamics 365FO



In one of my projects, We have a requirement to send the SSRS report as an attachment to an Email.

As everyone knows that this task is too simple in AX 2012, Where we save the file in client or server file systems and then send it as an Email attachment.

But the things are a bit more complicated when it comes to D365 in the cloud. You are no longer able to save the file locally as storage.

Following is the code to convert the SSRS report in Binaries 




public class ConvertReportPDF
{

    public static void main(Args _args)
    {
       
  
        Filename                        fileName = "P000173_AbcTest.pdf";
        SrsReportRunController    controller = new SrsReportRunController();
        SLD_TaxProfileContract   contract = new SLD_TaxProfileContract();
        SRSPrintDestinationSettings     settings;
        Array                           arrayFiles;
        System.Byte[]                   reportBytes = new System.Byte[0]();
        SRSProxy                        srsProxy;
        SRSReportRunService             srsReportRunService = new SrsReportRunService();
        Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;
        Map reportParametersMap;
        SRSReportExecutionInfo executionInfo = new SRSReportExecutionInfo();
        ;

  
        contract.parmAccountNum('K-VDR-000001');
        contract.parmAccountType(SLD_AccountType::Vendor);
        // Provide details to controller and add contract
        controller.parmArgs(_args);
        controller.parmReportName(ssrsReportStr(SLD_TaxProfile, Report));
        controller.parmShowDialog(false);
        controller.parmLoadFromSysLastValue(false);
        controller.parmReportContract().parmRdpContract(contract);
        // Provide printer settings
        settings = controller.parmReportContract().parmPrintSettings();
        settings.printMediumType(SRSPrintMediumType::File);
        settings.fileName(fileName);
        settings.fileFormat(SRSReportFileFormat::PDF);

        // Below is a part of code responsible for rendering the report
        controller.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
        controller.parmReportContract().parmReportExecutionInfo(executionInfo);

        srsReportRunService.getReportDataContract(controller.parmreportcontract().parmReportName());
        srsReportRunService.preRunReport(controller.parmreportcontract());
        reportParametersMap = srsReportRunService.createParamMapFromContract(controller.parmReportContract());
        parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);

        srsProxy = SRSProxy::constructWithConfiguration(controller.parmReportContract().parmReportServerConfig());
        // Actual rendering to byte array
        reportBytes = srsproxy.renderReportToByteArray(controller.parmreportcontract().parmreportpath(),
                                              parameterValueArray,
                                              settings.fileFormat(),
                                              settings.deviceinfo());
    



        // You can also convert the report Bytes into an xpp BinData object if needed
        container binData;
        Binary binaryData;
        System.IO.MemoryStream mstream = new System.IO.MemoryStream(reportBytes);
        binaryData = Binary::constructFromMemoryStream(mstream);
       // System.IO.File::WriteAllBytes("C:\\backup\\"+fileName,reportBytes); // You can save the file on your local instance for verification
       

        if(binaryData)
        {
            binData = binaryData.getContainer();
        }
        Map map=new Map (Types::String,Types::String);
        map.insert("message","Its working fine for me");
        SLD_EmailAttachment::sendPDFEamilAttachment("EmailRecpt","en-us","ShaikhSohailHussain@gmail.com",map,binData,"P000173_AbcTest");
    }

}


USE following code to send as Email Attachment 



class SLD_EmailAttachment

{


  

    public static void sendPDFEamilAttachment( SysEmailId      _emailId,
        LanguageId      _language,
        SysEmailAddress             _emailAddr,
        Map             _mappings,container _binData,str _fileName)
    {
        SysEmailItemId                   nextEmailItemId;
        SysEmailTable                    sysEmailTable;
        SysEmailMessageTable             sysEmailMessageTable;
        SysEmailContents                 sysEmailContents;
        SysOutgoingEmailTable            outgoingEmailTable;
        SysOutgoingEmailData             outgoingEmailData;
        Filename filename, FileExtension;
      
        FileExtension=".pdf";
       
        select sysEmailTable
               join    sysEmailMessageTable
                where sysEmailMessageTable.EmailId==sysEmailTable.EmailId
                    && sysEmailMessageTable.EmailId== _emailId
                    && sysEmailMessageTable.LanguageId==_language;
       
        if(sysEmailTable.RecId>0)
        {
            sysEmailContents=SysEmailMessage::stringExpand(sysEmailMessageTable.Mail, _mappings);
            nextEmailItemId = EventInbox::nextEventId();
      
            filename =strFmt("%1_%2.pdf",nextEmailItemId,_fileName);
    
    
            outgoingEmailTable.clear();
            outgoingEmailTable.Origin=sysEmailTable.Description;
            outgoingEmailTable.EmailItemId = nextEmailItemId;
            outgoingEmailTable.IsSystemEmail = NoYes::Yes;
            outgoingEmailTable.Sender = sysEmailTable.SenderAddr;
            outgoingEmailTable.SenderName = sysEmailTable.SenderName;
            outgoingEmailTable.Recipient = _emailAddr;
            outgoingEmailTable.Subject = SysEmailMessage::stringExpand(sysEmailMessageTable.Subject, _mappings);
            outgoingEmailTable.Priority = eMailPriority::High;
            outgoingEmailTable.WithRetries = NoYes::NO;
            outgoingEmailTable.RetryNum = 0;
            outgoingEmailTable.UserId = curUserId();
            outgoingEmailTable.Status = SysEmailStatus::Unsent;
            outgoingEmailTable.Message =  sysEmailContents;
            outgoingEmailTable.LatestStatusChangeDateTime = DateTimeUtil::getSystemDateTime();
            outgoingEmailTable.TemplateId= _emailId;
            outgoingEmailTable.insert();


            if(conLen(_binData)>0)
            {
                outgoingEmailData.clear();

                outgoingEmailData.EmailItemId = nextEmailItemId;
                outgoingEmailData.DataId = 1;
                outgoingEmailData.EmailDataType = SysEmailDataType::Attachment;
                outgoingEmailData.Data = _binData;
                outgoingEmailData.FileName = filename;
                outgoingEmailData.FileExtension =FileExtension;

                outgoingEmailData.insert();
            }
        }
    }

}



Azure Application Registration

 Azure Application Registration with permission


I was facing an issue with Azure Application authentication from OAuthHelper for the following case.

User-1 (member type) has created an application(i.e. AppB) on Azure Portal and grant the required permission(Microsoft Dynamics ERP, Windows Azure AD) and user-A can authenticate himself via OAuthHelper expected behavior [basic configuration need to set App-id, username, password in config file]

User-1 added user-2 from Azure Portal as application owner against the same application(i.e. AppB) and grant permission.

User-2 (member type) was unable to authenticate via OAuthHelper which was strange because User-1 already added him as application owner on Portal.
Exception faced: The user or administrator has not consented to use the application with ID <AppId> named AppB. 
This exception raised when calling
authenticationResult = authenticationContext.AcquireTokenAsync(aadResource, aadClientAppId, userCredential).Result;
 
I did few hit and try. Following fix work for me.

User-2 login on Azure Portal, select the same application(i.e. AppB), and press grant permission.

Now User-2 is able to authenticate via OAuthHelper no more exception

Virtual Fields Vs Computed Fields

  Virtual Field: A virtual field in D365FO is a field that doesn't have a direct representation in the database. It's a field that y...