Bhoopathi

"Be Somebody Nobody Thought You could Be"

Wednesday, December 21

Custom WorkFlow to Send Email with PDF formatted Report as Attachment

Custom WorkFlow to Send Email with PDF formatted Report as Attachment

Introduction

In some cases, we have to send Email to customers with a Report in Pdf format as an attachment.

Background

Once I had the same requirement. To do this, we have to follow three steps.
  1. First to retrieve the Report,
  2. Second to convert the Report to PDF format and
  3. Last to send an Email with the PDF as attachment.

Code

To achieve this, I have written a Custom Workflow.
Here is the code snippet to get it done. This code is for CRM OnPremise only. I have not tried in CRM Online.
using System;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using CustomWorkflows.ReportService; //Have to add the Reporting Service as Web Reference
 
namespace SendReport
{
    public class SendReport : CodeActivity
    {
        protected override void Execute(CodeActivityContext executionContext)
        {
            try
            {
                IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
 
                Guid accountId = context.PrimaryEntityId;
                byte[] result = null;
 
                CustomWorkflows.ReportService.ReportExecutionService rs = new ReportExecutionService();
 
                // Credential to connect with CRM
                rs.Credentials = new System.Net.NetworkCredential(username, password, domain);
 
                // Setting the URL of the Reporting Server
                rs.Url = "http://test10:80/ReportServer/ReportExecution2005.asmx";
 
                string reportPath = "/Test_MSCRM/TestReport";
                // Specify the report path from the reporting server
                // Note: To get the report name, report must be published for the external use.
                // To do this edit the report from CRM and publish it for external use.
                // After publishing it for external use report name will be visible in the reporting server instead of the report id.
 
                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                string[] streamIDs = null;
 
                ExecutionInfo execInfo = new ExecutionInfo();
                ExecutionHeader execHeader = new ExecutionHeader();
                rs.ExecutionHeaderValue = execHeader;
                execInfo = rs.LoadReport(reportPath, historyID);
 
                String SessionId = rs.ExecutionHeaderValue.ExecutionID;
 
                result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
 
                //Create email activity
                Entity email = new Entity();
                email.LogicalName = "email";
                email.Attributes.Add("regardingobjectid", new EntityReference("account", accountId);
 
                //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                EntityReference from = new EntityReference("systemuser", senderUserId);
                EntityReference to = new EntityReference("contact", recieverUserId);
                EntityReference cc = new EntityReference("contact", recieverCCUserId);
 
                //Creating party list
                Entity fromParty = new Entity("activityparty");
                fromParty.Attributes.Add("partyid", from);
                Entity toParty = new Entity("activityparty");
                toParty.Attributes.Add("partyid", to);
                Entity ccParty = new Entity("activityparty");
                ccParty.Attributes.Add("partyid", cc);
 
                EntityCollection collFromParty = new EntityCollection();
                collFromParty.EntityName = "systemuser";
                collFromParty.Entities.Add(fromParty);
 
                EntityCollection collToParty = new EntityCollection();
                collToParty.EntityName = "contact";
                collToParty.Entities.Add(toParty);
 
                EntityCollection collccParty = new EntityCollection();
                collccParty.EntityName = "contact";
                collccParty.Entities.Add(ccParty);
 
                // Adding from, to and cc to the email
                email.Attributes.Add("from", collFromParty);
                email.Attributes.Add("to", collToParty);
                email.Attributes.Add("cc", collccParty);
 
                email.Attributes.Add("subject", "Here goes subject message.. : ");
                email.Attributes.Add("description", "Here goes description text..");
                Guid emailID = service.Create(email); // Create the email
 
                // Attaching Pdf Report
                int NextActorID = new int();
                RetrieveEntityRequest request = new RetrieveEntityRequest();
                request.LogicalName = "email";
                RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
                int objecttypecode = response.EntityMetadata.ObjectTypeCode.Value;
 
                Entity attachment = new Entity("activitymimeattachment");
                attachment.Attributes.Add("subject", "Report");
                attachment.Attributes.Add("filename", "Report.pdf");
                attachment.Attributes.Add("body", Convert.ToBase64String(result));
                attachment.Attributes.Add("filesize", Convert.ToInt32(result.Length.ToString()));
                attachment.Attributes.Add("mimetype", "text/plain");
                attachment.Attributes.Add("attachmentnumber", NextActorID);
                attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
                attachment.Attributes.Add("objecttypecode", objecttypecode);
                service.Create(attachment); //Create the attachment
 
                // Sending email
                SendEmailRequest reqSendEmail = new SendEmailRequest();
                reqSendEmail.EmailId = emailID;
                reqSendEmail.TrackingToken = "";
                reqSendEmail.IssueSend = true;
                SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
            }
            catch (Exception err)
            {
                // Throw error message
            }
        }
    }
}