Thursday 18 July 2019

Dynamics - PDF Generator


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.

  1. Create a new workflow named. Ex-Customer Invoice.
  2. Create Email with all create information.
  3. 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 void Execute(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 void Execute(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 = new SendEmailRequest();
                    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 new InvalidPluginExecutionException("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.

No comments:

Post a Comment

Field Security Profile - Based on Owner

 Recently received requirement related to Field security profile. Expectation : - 1.       Set to users need access of secure attributes. 2....

Test