In 2017, a third party provide a solution that use to generate PDF from CRM templates.
In recently, Dynamics 365 organization I have seen this solution as a part of Microsoft out-of-box solution list. And this solution is free.
Also Microsoft still not taken this feature as they done for Resco field service module.
So we can see all entity, web resource etc. solution component with third party prefix.
We always need to send PDF to customer for quotation, Sales order or Invoices etc. In On-Premise CRM organization it was easy because we can use register plugin is none Isolation Mode and access other iText like assemblies.
But in Online Dynamics 365 it is not possible.
You can refer below link to get User Guide.
Working:-
Click on “Generate PDF Configuration” button top of solution lists and it will open “hcl_pdf_GeneratePDFConfigurator” web resource for us. We can configure/Enable list of Entity having document templates.
Form here we can remove the generate PDF feature for an entity and template whenever needed.
After configuration is done, we can see a new button configured entity. However this button also visible on create form, which have no use until record is created.
Click on Generate PDF button it will open “hcl_pdf_GeneratePDF” web resource with some query string information from there we can generate our PDF and download or save in note section for selected document template. I have seen it worked of Word Templates.
However I have not seen preview as showing in user guide. But download and add to note working fine.
We can also use this solution for sending email with PDF with some customization and configuration.
- Create a new workflow named. Ex-Customer Invoice.
- Create Email with all create information.
- Create custom workflow to get record (Invoice, Quote etc.) Guid.
public class GetRecordIDFromURL : CodeActivity
{
#region variable used
[RequiredArgument]
[Input("RecordURL")]
public InArgument<string> RecordURL { get; set; }
[RequiredArgument]
[Output("RecordId")]
public OutArgument<string> RecordId { get; set; }
string traceMessage = string.Empty;
#endregion
protected override voidExecute(CodeActivityContext executionContext)
{
//Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
//Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
traceMessage = "Workflow started.";
tracingService.Trace(traceMessage);
if (RecordURL.Get<string>(executionContext) != null)
{
RecordId.Set(executionContext, RecordURL.Get<string>(executionContext).Substring(RecordURL.Get<string>(executionContext).IndexOf("&id=")+4, 36));
}
}
}
4. Call Action “Generate PDF Action”. It will return pdf data in “PDFBinaryData” parameter.
5. Create custom workflow to add “activitymimeattachment” to email.
var email = context.InputParameterOrDefault<EntityReference>("Email");
var output = context.InputParameterOrDefault<String>("output");
if (email!=null)//CreateEmailAttachment
{
Microsoft.Xrm.Sdk.Entity ActivityMimeAttachment = new Microsoft.Xrm.Sdk.Entity("activitymimeattachment");
ActivityMimeAttachment["subject"] = report.GetAttributeValue<string>("name");
ActivityMimeAttachment["filename"] = "Invoice.pdf";
ActivityMimeAttachment["body"] = output;
ActivityMimeAttachment["attachmentnumber"] = 1;
ActivityMimeAttachment["objectid"] = email;
ActivityMimeAttachment["objecttypecode"] = "email";
service.Create(ActivityMimeAttachment);
}
6. Create custom workflow to send that Email.
public class SendEmail: CodeActivity
{
private string traceMessage = string.Empty;
[RequiredArgument]
[Input("Email")]
[ReferenceTarget("email")]
public InArgument<EntityReference> Email
{
get;
set;
}
#region Execute function
protected override voidExecute(CodeActivityContext executionContext)
{
//Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
//Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
try
{
traceMessage = "Workflow started.";
tracingService.Trace(traceMessage);
if (Email.Get<EntityReference>(executionContext) != null)
{
SendEmailRequest SendEmailRequest = newSendEmailRequest();
SendEmailRequest.EmailId=(Email.Get<EntityReference>(executionContext).Id);
SendEmailRequest.TrackingToken="";
SendEmailRequest.IssueSend=(true);
SendEmailResponse Response =(SendEmailResponse) service.Execute(SendEmailRequest);
}
else
traceMessage += " No Record found to update.";
}
catch (Exception ex)
{
tracingService.Trace(traceMessage);
throw newInvalidPluginExecutionException("error occured in SendEmail workflow: " + ex.Message.ToString());
}
}
#endregion
}
Update action as per requirement.
Once this workflow will run an email with Invoice PDF will sent to customer.
You can also test this Action from XRMToolBox.
In result you will see PDF content in binary format that can direct use in email or Note attachment.
Please share your feedback.

































