web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

CRM ONLINE 2013: On Approval Of Quotation, Run Report, Generate PDF and Send an Email With PDF as attachment

(0) ShareShare
ReportReport
Posted on by

Hi,

I am using CRM ONLINE 2013.

How to automate below process?

1. On Approval Of Quotation, Run Report.

2. Generate PDF.

3. Send an Email With PDF as attachment.

As i have gone through many forums for this topic, but creating a plugin code for generating Report PDF is not possible in CRM ONLINE.

So, What is the alternate way to do this..?

Thanks.

*This post is locked for comments

I have the same question (0)
  • Community Member Profile Picture
    on at

    Hi ,

    If you are onterested in a 3rd party solution you can take a look into our DocumentsCorePack Server-Base.

    Our Add-on gives you the possibility to design your template in Word . Based on this templates DCP Server-Based can generate documents in various file formats. This documents will be generated on the server triggered by a workflow or a dialog.

    Of course, you are able to attach the generated document to an email, save it toma Sharepoint location, send email and many more.

    All this works for CRM Online and On Premise.

    Let me know if you are interested.

  • Suggested answer
    ScottDurow Profile Picture
    21 on at

    As you've no doubt discovered, the Online Reporting Services instance doesn't provide access to the SSRS web services.

    You have 3 options:

    1. Use an ISV solution such as Christian's (which works well!)

    2. Write code to generate the PDF using an open source PDF generation library

    3. Write a web service that is accessible by CRM online but hosted else where that has access to Reporting Services that maintains a copy of the database for reporting services purposes. You could retrieve the quote data from CRM using the SDK web services, insert it into the reporting database and grenade the report from there. The generated PDF could be returned as a base64 encoded string.

    Hope this helps,

    Scott

  • Verified answer
    Prashant Bhojani Profile Picture
    on at

    Hello , i have tried below code and it is working fine.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/.../xhtml1-transitional.dtd">

    <html xmlns="www.w3.org/.../xhtml">

    <head>

       <title></title>

       <script src="ajax.googleapis.com/.../script>

       <script type="text/javascript">

           if (typeof (SDK) == "undefined")

           { SDK = { __namespace: true }; }

           SDK.JScriptRESTDataOperations = {

               _context: function () {

                   if (typeof GetGlobalContext != "undefined")

                   { return GetGlobalContext(); }

                   else {

                       if (typeof Xrm != "undefined") {

                           return Xrm.Page.context;

                       }

                       else { return new Error("Context is not available."); }

                   }

               },

               _getServerUrl: function () {

                   var serverUrl = this._context().getServerUrl()

                   if (serverUrl.match(/\/$/)) {

                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);

                   }

                   return serverUrl;

               },

               _ODataPath: function () {

                   return this._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";

               },

               _errorHandler: function (req) {

                   return new Error("Error : " +

     req.status + ": " +

     req.statusText + ": " +

     JSON.parse(req.responseText).error.message.value);

               },

               _dateReviver: function (key, value) {

                   var a;

                   if (typeof value === 'string') {

                       a = /Date\(([-+]?\d+)\)/.exec(value);

                       if (a) {

                           return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));

                       }

                   }

                   return value;

               },

               Create: function (object, type, successCallback, errorCallback) {

                   var req = new XMLHttpRequest();

                   req.open("POST", this._ODataPath() + type + "Set", true);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                   req.onreadystatechange = function () {

                       if (this.readyState == 4 /* complete */) {

                           if (this.status == 201) {

                               successCallback(JSON.parse(this.responseText, SDK.JScriptRESTDataOperations._dateReviver).d);

                           }

                           else {

                               errorCallback(SDK.JScriptRESTDataOperations._errorHandler(this));

                           }

                       }

                   };

                   req.send(JSON.stringify(object));

               },

               Retrieve: function (id, type, successCallback, errorCallback) {

                   var req = new XMLHttpRequest();

                   req.open("GET", this._ODataPath() + type + "Set(guid'" + id + "')", true);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                   req.onreadystatechange = function () {

                       if (this.readyState == 4 /* complete */) {

                           if (this.status == 200) {

                               successCallback(JSON.parse(this.responseText, SDK.JScriptRESTDataOperations._dateReviver).d);

                           }

                           else {

                               errorCallback(SDK.JScriptRESTDataOperations._errorHandler(this));

                           }

                       }

                   };

                   req.send();

               },

               Update: function (id, object, type, successCallback, errorCallback) {

                   var req = new XMLHttpRequest();

                   req.open("POST", this._ODataPath() + type + "Set(guid'" + id + "')", true);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                   req.setRequestHeader("X-HTTP-Method", "MERGE");

                   req.onreadystatechange = function () {

                       if (this.readyState == 4 /* complete */) {

                           if (this.status == 204 || this.status == 1223) {

                               successCallback();

                           }

                           else {

                               errorCallback(SDK.JScriptRESTDataOperations._errorHandler(this));

                           }

                       }

                   };

                   req.send(JSON.stringify(object));

               },

               Delete: function (id, type, successCallback, errorCallback) {

                   var req = new XMLHttpRequest();

                   req.open("POST", this._ODataPath() + type + "Set(guid'" + id + "')", true);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                   req.setRequestHeader("X-HTTP-Method", "DELETE");

                   req.onreadystatechange = function () {

                       if (this.readyState == 4 /* complete */) {

                           if (this.status == 204 || this.status == 1223) {

                               successCallback();

                           }

                           else {

                               errorCallback(SDK.JScriptRESTDataOperations._errorHandler(this));

                           }

                       }

                   };

                   req.send();

               },

               RetrieveMultiple: function (type, filter, successCallback, errorCallback) {

                   if (filter != null) {

                       filter = "?" + filter;

                   }

                   else { filter = ""; }

                   var req = new XMLHttpRequest();

                   req.open("GET", this._ODataPath() + type + "Set" + filter, true);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                   req.onreadystatechange = function () {

                       if (this.readyState == 4 /* complete */) {

                           if (this.status == 200) {

                               successCallback(JSON.parse(this.responseText, SDK.JScriptRESTDataOperations._dateReviver).d.results);

                           }

                           else {

                               errorCallback(SDK.JScriptRESTDataOperations._errorHandler(this));

                           }

                       }

                   };

                   req.send();

               },

               __namespace: true

           };

       </script>

       <script type="text/javascript">

           //Create Email and link it with Order as Regarding field

           var Xrm;

           var email = new Object();

           var ownerID = "";

           var CustomerId = "";

           if (window.opener) { Xrm = window.opener.Xrm; }

           else if (window.parent) { Xrm = window.parent.Xrm; }

           //Get ownerid who send email of quotation to customer

           function GetOwnerID() {

               var owner = Xrm.Page.getAttribute("ownerid").getValue();

               ownerID = owner[0].id;

               var ownerName = owner[0].name;

               var entityType = owner[0].entityType;

               GetToEmailGUID();

           }

           //Get customerid who receive email of quotation from owner

           function GetToEmailGUID() {

               var Customer = Xrm.Page.getAttribute('customerid').getValue();

               CustomerId = Customer[0].id;

               var CustomerName = Customer[0].name;

               var entityType = Customer[0].entityType;

               //if CustomerId is type of "Account" then get Primary Contact id of that account

               if (entityType == "account") {

                   var contact = Xrm.Page.getAttribute("customerid").getValue();

                   if (contact === null) return;

                   var serverUrl = Xrm.Page.context.getClientUrl();

                   var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/AccountSet(guid'" + contact[0].id + "')?$select=PrimaryContactId";

                   var req = new XMLHttpRequest();

                   req.open("GET", oDataSelect, false);

                   req.setRequestHeader("Accept", "application/json");

                   req.setRequestHeader("Content-Type", "application/json;charset=utf-8");

                   req.onreadystatechange = function () {

                       if (req.readyState === 4) {

                           if (req.status === 200) {

                               var retrieved = JSON.parse(req.responseText).d;

                               CustomerId = retrieved.PrimaryContactId.Id;

                           }

                           else {

                               alert(this.statusText);

                           }

                       }

                   };

                   req.send();

               }

           }

           function CreateEmail() {

               GetOwnerID();

               email.Subject = "Email with Report Attachment";

               //Set The current order as the Regarding object

               email.RegardingObjectId = {

                   Id: Xrm.Page.data.entity.getId(),    //Get the current entity Id , here OrderId

                   LogicalName: Xrm.Page.data.entity.getEntityName()//Get the current entity name, here it will be “salesOrder”

               };

               //Create Email Activity

               SDK.JScriptRESTDataOperations.Create(email, "Email", EmailCallBack, function (error) { alert(error.message); });

           }

           // Email Call Back function

           function EmailCallBack(result) {

               email = result; // Set the email to result to use it later in email attachment for retrieving activity Id

               var activityPartyFrom = new Object();

               // Set the From party of the ActivityParty to relate an entity with Email From field

               activityPartyFrom.PartyId = {

                   Id: CustomerId, //"79EBDD26-FDBE-E311-8986-D89D6765B238",  // id of entity you want to associate this activity with.          

                   LogicalName: "contact"

               };

               // Set the "activity" of the ActivityParty

               activityPartyFrom.ActivityId = {

                   Id: result.ActivityId,

                   LogicalName: "email"

               };

               // Now set the participation type that describes the role of the party on the activity).

               activityPartyFrom.ParticipationTypeMask = { Value: 2 }; // 2 means ToRecipients

               // Create the from ActivityParty for the email

               SDK.JScriptRESTDataOperations.Create(activityPartyFrom, "ActivityParty", ActivityPartyFromCallBack, function (error) { alert(error.message); });

               var activityPartyTo = new Object();

               // Set the From party of the ActivityParty to relate an entity with Email From field

               activityPartyTo.PartyId = {

                   Id: ownerID, //"79EBDD26-FDBE-E311-8986-D89D6765B238",  // id of entity you want to associate this activity with.          

                   LogicalName: "systemuser"

               };

               // Set the "activity" of the ActivityParty  

               activityPartyTo.ActivityId = {

                   Id: result.ActivityId,

                   LogicalName: "email"

               };

               // Now set the participation type that describes the role of the party on the activity).    

               activityPartyTo.ParticipationTypeMask = { Value: 1 }; // 1 means Sender

               // Create the from ActivityParty

               SDK.JScriptRESTDataOperations.Create(activityPartyTo, "ActivityParty", ActivityPartyToCallBack, function (error) { alert(error.message); });

           }

           //ActivityParty From Callback

           function ActivityPartyFromCallBack(result) {

           }

           //ActivityParty To Callback

           function ActivityPartyToCallBack(result) {

               GetReportId('Quotation');

           }

           //Create attachment for the created email

           function CreateEmailAttachment() {

               //get reporting session and use the params to convert a report in PDF

               var params = getReportingSession();

               //Email attachment parameters

               var activitymimeattachment = Object();

               activitymimeattachment.ObjectId = Object();

               activitymimeattachment.ObjectId.LogicalName = "email";

               activitymimeattachment.ObjectId.Id = email.ActivityId;

               activitymimeattachment.ObjectTypeCode = "email",

                   activitymimeattachment.Subject = "File Attachment";

               activitymimeattachment.Body = encodePdf(params);

               activitymimeattachment.FileName = "Report.pdf";

               activitymimeattachment.MimeType = "application/pdf";

               //Attachment call

               SDK.JScriptRESTDataOperations.Create(activitymimeattachment, "ActivityMimeAttachment", ActivityMimeAttachmentCallBack, function (error) { alert(error.message); });

           }

           //ActivityMimeAttachment CallBack function

           function ActivityMimeAttachmentCallBack(result) {

               var features = "location=no,menubar=no,status=no,toolbar=no,resizable=yes";

               var width = "800px";

               var height = "600px";

               window.open(Xrm.Page.context.getServerUrl() + "main.aspx?etc=" + 4202 + "&pagetype=entityrecord&id=" + email.ActivityId, "_blank", features);

               // To open window which works in outlook and IE both

               //openStdWin(Xrm.Page.context.getServerUrl() + "main.aspx?etc=" + 4202 + "&pagetype=entityrecord&id=" + email.ActivityId, "_blank", width, height, features);

           }

           //This method will get the reportId based on a report name that will be used in            getReportingSession() function

           function GetReportId(reportName) {

               var oDataSetName = "ReportSet";

               var columns = "ReportId";

               var filter = "Name eq '" + reportName + "'";

               retrieveMultiple(oDataSetName, columns, filter, onSuccess);

           }

           function retrieveMultiple(odataSetName, select, filter, successCallback) {

               var serverUrl = Xrm.Page.context.getServerUrl();

               var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

               var odataUri = serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "?";

               if (select) {

                   odataUri += "$select=" + select + "&";

               }

               if (filter) {

                   odataUri += "$filter=" + filter;

               }

               $.ajax({

                   type: "GET",

                   contentType: "application/json; charset=utf-8",

                   datatype: "json",

                   url: odataUri,

                   beforeSend: function (XMLHttpRequest) {

                       XMLHttpRequest.setRequestHeader("Accept", "application/json");

                   },

                   success: function (data) {

                       if (successCallback) {

                           if (data && data.d && data.d.results) {

                               successCallback(data.d.results);

                           }

                           else if (data && data.d) {

                               successCallback(data.d);

                           }

                           else {

                               successCallback(data);

                           }

                       }

                   },

                   error: function (XmlHttpRequest, errorThrown) {

                       if (XmlHttpRequest && XmlHttpRequest.responseText) {

                           alert("Error while retrieval ; Error – " + XmlHttpRequest.responseText);

                       }

                   }

               });

           }

           function onSuccess(data) {

               reportId = data[0].ReportId.replace('{', ").replace('}', ");

               CreateEmailAttachment(); // Create Email Attachment

           }

           //Gets the report contents

           function getReportingSession() {

               var pth = Xrm.Page.context.getServerUrl() + "/CRMReports/rsviewer/reportviewer.aspx";

               var retrieveEntityReq = new XMLHttpRequest();

               var Id = Xrm.Page.data.entity.getId();

               var quotationGUID = Id.replace('{', ""); //set this to selected quotation GUID

               quotationGUID = quotationGUID.replace('}', "");

               var reportName = "Quotation"; //set this to the report you are trying to download

               var reportID = "7C39D18F-1DC6-E311-8986-D89D6765B238"; //set this to the guid of the report you are trying to download

               var rptPathString = ""; //set this to the CRMF_Filtered parameter

               var strParameterXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'><entity name='quote'><all-attributes /><filter type='and'><condition attribute='quoteid' operator='eq' uitype='quote' value='" + quotationGUID + "' /> </filter></entity></fetch>";

               retrieveEntityReq.open("POST", pth, false);

               retrieveEntityReq.setRequestHeader("Accept", "*/*");

               retrieveEntityReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

               rptPathString = "id=%7B" + reportID + "%7D&uniquename=" + Xrm.Page.context.getOrgUniqueName() + "&iscustomreport=true&reportnameonsrs=&reportName=" +

                               reportName + "&isScheduledReport=false&p:CRMAF_Filteredquote=" + strParameterXML;

               //remove the part starting from &p:salesorderid if your report has no parameters

               retrieveEntityReq.send(rptPathString);

               var x = retrieveEntityReq.responseText.indexOf("ReportSession=");

               var ret = new Array();

               ret[0] = retrieveEntityReq.responseText.substr(x + 14, retrieveEntityReq.responseText.indexOf("&", x) - x - 14); //the session id

               x = retrieveEntityReq.responseText.indexOf("ControlID=");

               ret[1] = retrieveEntityReq.responseText.substr(x + 10, retrieveEntityReq.responseText.indexOf("&", x) - x - 10); //the control id

               return ret;

           }

           var bdy = new Array();

           var bdyLen = 0;

           function concat2Bdy(x) {

               bdy[bdyLen] = x;

               bdyLen++;

           }

           function encodePdf(params) {

               bdy = new Array();

               bdyLen = 0;

               var retrieveEntityReq = new XMLHttpRequest();

               var pth = Xrm.Page.context.getServerUrl() + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + params[0] +

               "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + params[1] +

               "&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF";

               retrieveEntityReq.open("GET", pth, false);

               retrieveEntityReq.setRequestHeader("Accept", "*/*");

               retrieveEntityReq.send();

               BinaryToArray(retrieveEntityReq.responseBody);

               return encode64(bdy);

           }

           var StringMaker = function () {

               this.parts = [];

               this.length = 0;

               this.append = function (s) {

                   this.parts.push(s);

                   this.length += s.length;

               }

               this.prepend = function (s) {

                   this.parts.unshift(s);

                   this.length += s.length;

               }

               this.toString = function () {

                   return this.parts.join('');

               }

           }

           var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

           function encode64(input) {

               var output = new StringMaker();

               var chr1, chr2, chr3;

               var enc1, enc2, enc3, enc4;

               var i = 0;

               while (i < input.length) {

                   chr1 = input[i++];

                   chr2 = input[i++];

                   chr3 = input[i++];

                   enc1 = chr1 >> 2;

                   enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);

                   enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);

                   enc4 = chr3 & 63;

                   if (isNaN(chr2)) {

                       enc3 = enc4 = 64;

                   } else if (isNaN(chr3)) {

                       enc4 = 64;

                   }

                   output.append(keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4));

               }

               return output.toString();

           }      

       </script>

       <script type="text/vbscript">

       Function BinaryToArray(Binary)

              Dim i

              ReDim byteArray(LenB(Binary))

              For i = 1 To LenB(Binary)

                    byteArray(i-1) = AscB(MidB(Binary, i, 1))

                    concat2Bdy(AscB(MidB(Binary, i, 1)))

            Next

             BinaryToArray = byteArray

      End Function

       </script>

    </head>

    <body>

       <input type="button" onclick="CreateEmail();" value="Attach Report" />

    </body>

    </html>

  • Vivian Herbst Profile Picture
    95 on at

    Hi,

    I looked at the code that Prashant Bhojani Provided that was verified as the correct answer. Would anyone be able to assist on how to use this code because just adding that code as a JScript Web resource and calling it with a button wont work.

  • Tin Profile Picture
    1,562 on at

    Hey,Is above code is working for you if yes please suggest me how I also having requirement like you have.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans