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.
- First to retrieve the Report,
- Second to convert the Report to PDF format and
- 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.
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 Referencenamespace 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 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 } } }}