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

  • Question

  • 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.

    Tuesday, April 29, 2014 7:30 AM

Answers

  • Hello, 

    i have tried below code and it is working fine for me.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></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>
    

    • Marked as answer by PB5590 Tuesday, May 6, 2014 5:44 AM
    Tuesday, May 6, 2014 5:44 AM

All replies

  • Hello, 

    i have tried below code and it is working fine for me.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></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>
    

    • Marked as answer by PB5590 Tuesday, May 6, 2014 5:44 AM
    Tuesday, May 6, 2014 5:44 AM
  • Hello there - this is awesome. However, it doens't work for me in CRM 2013 online.  At first, I missed the primary contact so it threw contact ID being 000000000. Then after I had associated a primary contact to the Account and then run the "Attach Report" it does nothing. If I press again, i get the internal error!!..

    I put a webresource of Type Webpage on the Quote Form. 

    web-resource contains the above code with necessary modifications. 

    I open a quote (draft or Active), then Click on "Attach Report" webresource -- no response!! any help is appreciated. 

    Note: I changed the report ID as from the URL 

    https://abccompany.crm.dynamics.com/crmreports/viewer/viewer.aspx?action=run&context=records&helpID=abccompany%20Lic%20Quote.rdl&id=%7b30xxxxxx-4dxx-exxx-8bxx-78xxxxxxxxx1%7d&records=%7bxxxxxxxx-xxxxxxxxxxxxx-xxxxxx%7d&recordstype=1084

    var reportID =   "30xxxxxx-4dxx-exxx-8bxx-78xxxxxxxxx1"

    also note - this is a custom fetch xml report for the Quote.   

    It does create email activity but no report attached pdfs.  

    I changed the report to a system report, again no attachments found!! 

    I notice the below in the Email activity: 

    Email Subject -- Email with Report Attachment CRM:0405

    From and To columns are filled in correctly. 

    Regarding Column -  "The CRM Quote"

    message body  is empty..

    No report attachments found!!  

    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 = "ABC Lic Quote"; //set this to the report you are trying to download
                //var reportID = "7CXXXXXXXXXXXXXXXXXXXXXXX"; //set this to the guid of the report you are trying to download
                var reportID =   "30XXXXXXXXXXXXXXXXXXX1"
                               
                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;
            }



     


    • Edited by CRM elite Wednesday, July 30, 2014 4:39 PM
    Wednesday, July 30, 2014 3:49 PM
  • Any updates from anyone? Appreciate it. 
    Wednesday, July 30, 2014 7:02 PM
  • This code works perfect to me also but couldn't able to read the pdf file for the created email record. Could you please help me to resolve this problem. This is my mail account:- ganesh1028@live.in

    Wednesday, January 28, 2015 12:35 PM
  • This is my entire code mentioned below:-

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></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('ABM_Infotech_SalesQuote');
            }
            //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 = "Report1.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 = "ABM_Infotech_SalesQuote"; //set this to the report you are trying to download
                var reportID = "751089AA-74B8-E211-B52F-D8D3855B253B"; //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:ABMFilteredQuote=" + 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>

    Wednesday, January 28, 2015 12:39 PM
  • Could you please confirm the above source code open the pdf file successfully after created the email record?
    Wednesday, January 28, 2015 12:48 PM
  • We couldn't able to read the pdf file after created the email record in the CRM 2013 online(As Mentioned above source code).
    Wednesday, January 28, 2015 12:49 PM
  • Does it work for custom fetch xml report (crm 2013 online). or what changes I need to make? 
    Saturday, January 31, 2015 12:11 AM
  • The above code works fine to created email record and attach pdf file but couldn't able to open (or) read the pdf file.
    Friday, March 27, 2015 12:40 PM