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 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
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
}
}
}
}