Thursday, March 26, 2015

Send Email Report Workflow Activity

using System;
using System.Activities;
using System.Text;
using SendEmailPDFReport.ReportService; // Add Reporting Service as Web Reference
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using System.Collections.Generic;


namespace SendEmailPDFReport
{
    public class SendEmailPDF : CodeActivity
    {
        #region Input Parameters

        [Input("Report ID")]
        [ReferenceTarget("report")]
        public InArgument<EntityReference> ReportID { get; set; }

        [RequiredArgument]
        [Input("From")]
        [ReferenceTarget("queue")]
        public InArgument<EntityReference> From { get; set; }

        [RequiredArgument]
        [Input("To")]
        [ReferenceTarget("contact")]
        public InArgument<EntityReference> Recipient { get; set; }

        [RequiredArgument]
        [Input("Subject")]
        public InArgument<string> Subject { get; set; }

        [RequiredArgument]
        [Input("Report Parameter")]
        public InArgument<string> ReportParameter { get; set; }

        [RequiredArgument]
        [Input("Report URL")]
        public InArgument<string> ReportURL { get; set; }

        [RequiredArgument]
        [Input("E-mail")]
        [ReferenceTarget("email")]
        public InArgument<EntityReference> Email { get; set; }

        [RequiredArgument]
        [Input("Report Name")]
        public InArgument<string> ReportName { get; set; }


        #endregion

        protected override void Execute(CodeActivityContext context)
        {
            StringBuilder sb = new StringBuilder("Starting; ");

            try
            {
                //Create the tracing service
                ITracingService tracingService = context.GetExtension<ITracingService>();

                //-----------------------------------
                // Workflow Context & Service Objects
                //-----------------------------------

                IWorkflowContext workFlowContext = context.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(workFlowContext.InitiatingUserId);


                OrganizationServiceContext orgContext = new OrganizationServiceContext(service);

                //--------------------------
                // Obtain the Input Argument
                // Report EntityReference
                //--------------------------

                Guid RptID = this.ReportID.Get(context).Id;
                Guid fromUserID = this.From.Get(context).Id;
                Guid sendto = this.Recipient.Get(context).Id;
                string SubjectTitle = this.Subject.Get(context);
                string rptParams = this.ReportParameter.Get(context);
                string rptURL = this.ReportURL.Get(context);
                Guid Emailent = this.Email.Get(context).Id;
                string rptName = this.ReportName.Get(context);

                tracingService.Trace("Retrieving Input Argument" + "ReportID: " + RptID + "fromUserID : " + fromUserID + "sendto: " + sendto + "Emailent " + Emailent);

                sb.AppendFormat("Retrieving Input Argument" + "ReportID: " + RptID + "Queue : " + fromUserID + "contact: " + sendto + "Emailent " + Emailent);

                // Credential to connect with CRM
                ReportExecutionService rs = new ReportExecutionService();
                rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
                rs.Url = this.ReportURL.Get(context);

                byte[] result = null;

                //--------------------------
                // Specify the report path from the reporting server
                // Note: To get the report name, report must be published for the external use.
                // To do this edit the report from CRM and publish it for external use.
                // After publishing it for external use report name will be visible in the reporting server instead of the report id.
                //--------------------------

                string reportPath = string.Format("/{0}_MSCRM/CustomReports/{1}", workFlowContext.OrganizationName, ((EntityReference)context.GetValue(this.ReportID)).Id.ToString("B"));
                sb.AppendFormat("report path: {0}; ", reportPath);
                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";

                ParameterValue[] parameters = new ParameterValue[1];
                parameters[0] = new ParameterValue();
                parameters[0].Name = "ClaimID";
                parameters[0].Value = rptParams.ToString();

                sb.AppendFormat("Parameter length: {0}; ", parameters.Length.ToString());

                //string showHideToggle = null;
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                // ParameterValue[] reportHistoryParameters = null;
                string[] streamIDs = null;

                ExecutionInfo execInfo = new ExecutionInfo();

                ExecutionHeader execHeader = new ExecutionHeader();

                rs.ExecutionHeaderValue = execHeader;
                execInfo = rs.LoadReport(reportPath, historyID);

                if (execInfo.CredentialsRequired)
                {
                    List<DataSourceCredentials> dsCredentials = new List<DataSourceCredentials>();
                    foreach (DataSourcePrompt dsp in execInfo.DataSourcePrompts)
                    {
                        DataSourceCredentials credentials1 = new DataSourceCredentials();
                        credentials1.DataSourceName = dsp.Name;
                        sb.Append("; DataSourceName: " + credentials1.DataSourceName);

                        credentials1.UserName = workFlowContext.InitiatingUserId.ToString();
                        sb.Append("; username: " + workFlowContext.InitiatingUserId.ToString());
                        credentials1.Password = workFlowContext.OrganizationId.ToString();
                        sb.Append("; pword: " + workFlowContext.OrganizationId.ToString());

                        dsCredentials.Add(credentials1);
                    }
                    execInfo = rs.SetExecutionCredentials(dsCredentials.ToArray());
                }

                rs.SetExecutionParameters(parameters, "en-us");
                String SessionId = rs.ExecutionHeaderValue.ExecutionID;
                sb.Append("Attempting the render; ");

                try
                {
                    result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);

                    //Create email activity
                    Entity email = new Entity();
                    email.LogicalName = "email";
                    EntityReference regardingObject = new EntityReference("contact", sendto);
                    email.Attributes.Add("regardingobjectid", regardingObject);

                    //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                    EntityReference from = new EntityReference("queue", fromUserID);
                    EntityReference to = new EntityReference("contact", sendto);

                    //Creating party list
                    Entity fromParty = new Entity("activityparty");
                    fromParty.Attributes.Add("partyid", from);

                    Entity toParty = new Entity("activityparty");
                    toParty.Attributes.Add("partyid", to);

                    EntityCollection collFromParty = new EntityCollection();
                    collFromParty.EntityName = "queue";
                    collFromParty.Entities.Add(fromParty);

                    EntityCollection collToParty = new EntityCollection();
                    collToParty.EntityName = "contact";
                    collToParty.Entities.Add(toParty);

                    // Adding from & to  to the email
                    email.Attributes.Add("from", collFromParty);
                    email.Attributes.Add("to", collToParty);                    

                    email.Attributes.Add("subject", "Test Report");
                    email.Attributes.Add("description", "Test description text..");
                    // Create the email
                    Guid emailID = service.Create(email);


                    // Attaching Pdf Report
                    //int NextActorID = new int();
                    RetrieveEntityRequest request = new RetrieveEntityRequest();
                    request.LogicalName = "email";
                    RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
                    int objecttypecode = response.EntityMetadata.ObjectTypeCode.Value;

                    Entity attachment = new Entity("activitymimeattachment");
                    attachment["subject"] = "Report";
                    attachment["filename"] = "Report.pdf";
                    attachment["body"] = Convert.ToBase64String(result);
                    attachment["filesize"] = result.Length;
                    attachment["mimetype"] = "text/plain";
                    attachment["attachmentnumber"] = 1;
                    attachment["objectid"] = new EntityReference("email", new Guid(email.Id.ToString()));
                    attachment["objecttypecode"] = objecttypecode;

                    service.Create(attachment);

                    // Sending email
                    SendEmailRequest SendEmail = new SendEmailRequest();
                    SendEmail.EmailId = emailID;
                    SendEmail.IssueSend = true;
                    SendEmail.TrackingToken = "";
                    SendEmailResponse res = (SendEmailResponse)service.Execute(SendEmail);
                }

                catch (Exception err)
                {
                    throw new Exception(err.Message.ToString());
                }

            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException("An error occurred attaching the pdf: " + ex.Message + ": " + sb.ToString());
            }




        }
    }
}

Monday, March 9, 2015

Retrieve Metadata of a Boolean (Two Options) Attribute in Microsoft Dynamics CRM 2011/2013


Code to retrieve the boolean (Two Options) attribute metadata in CRM 2011. You need to pass the boolean value to get the Text.


public static string GetBoolText(IOrganizationService service, string entitySchemaName, string attributeSchemaName, bool value)
        {
            RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest
            {
                EntityLogicalName = entitySchemaName,
                LogicalName = attributeSchemaName,
                RetrieveAsIfPublished = true
            };
            RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
            BooleanAttributeMetadata retrievedBooleanAttributeMetadata = (BooleanAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;
            string boolText = string.Empty;
            if (value)
            {
                boolText = retrievedBooleanAttributeMetadata.OptionSet.TrueOption.Label.UserLocalizedLabel.Label;
            }
            else
            {
                boolText = retrievedBooleanAttributeMetadata.OptionSet.FalseOption.Label.UserLocalizedLabel.Label;
            }
            return boolText;
        }

Friday, March 6, 2015

Set Option Set by OptionSet Text

function SetValue(optionsetAttribute, optionText)
{
 var options = Xrm.Page.getAttribute(optionsetAttribute).getOptions();
 for(i = 0; i < options.length; i++)
 {
  if (options[i].text == optionText)
   Xrm.Page.getAttribute(optionsetAttribute).setValue(options[i].value);
 }
}

Calling of the function

SetValue("new_country", "India")

Multi Pick List in CRM 2011/2013

I have a one req. in one of the CRM Projects where user want multiple selection option in Option Set

we can create a Multiple Pick List for Dynamic CRM 2011/2013 form too.


User can enter multiple data from Pick List by Checkbox. This will also work on in major browsers (IE, Firefox, Chrome). See the below screen shot.



Below is the js code:

// var_sc_optionset >>  Provide schema-name for Option Set field
// var_sc_optionsetvalue >> Provide schema-name for field which will
//                          store the multi selected values for Option Set
// OS >> Provide Option Set field object
//       (Ex:- document.getElementById("Option Set field schema-name"))
// OSV >> Provide text field object which will store the
//        multi selected values for Option Set
//       (Ex:- document.getElementById("text field schema-name"))

//Method to convert an optionset to multi select Option Set
function ConvertToMultiSelect(var_sc_optionset, var_sc_optionsetvalue, OS, OSV) {

    if (OS != null && OSV != null) {
        OS.style.display = "none";

        // Create a DIV container
        var addDiv = document.createElement("div");
        addDiv.id = var_sc_optionsetvalue + "_m";
        addDiv.style.width = "100%";
        addDiv.style.height = "80px";
        addDiv.style.background = "#ffffff";
        addDiv.style.color = "white";
        addDiv.style.overflow = "auto";
        addDiv.style.border = "1px #6699cc solid";
        OS.parentNode.appendChild(addDiv);

        // Initialise checkbox controls
        for (var i = 1; i < OS.options.length; i++) {
            var pOption = OS.options[i];
            if (!IsChecked(pOption.innerHTML, OS, OSV)) {
                var addInput = document.createElement("input");
                addInput.type = "checkbox";
                addInput.style.border = "none";
                addInput.style.width = "25px";
                addInput.style.align = "left";
                addInput.style.color = "#000000";
                addInput.onclick = function () {
                    OnSave(OS, var_sc_optionsetvalue);
                    createTable(var_sc_optionsetvalue);
                }

            }
            else {
                var addInput = document.createElement("input");
                addInput.type = "checkbox";
                addInput.checked = "checked";
                addInput.style.border = "none";
                addInput.style.width = "25px";
                addInput.style.align = "left";
                addInput.style.color = "#000000";
                addInput.onclick = function () {
                    OnSave(OS, var_sc_optionsetvalue);
                    createTable(var_sc_optionsetvalue);
                }

            }
            //Create Label
            var addLabel = document.createElement("label");
            addLabel.style.color = "#000000";
            addLabel.innerHTML = pOption.innerHTML;

            var addBr = document.createElement("br"); //it's a 'br' flag

            OS.nextSibling.appendChild(addInput);
            OS.nextSibling.appendChild(addLabel);
            OS.nextSibling.appendChild(addBr);
        }
    }
}

//Supported functions

// Check if it is selected
function IsChecked(pText, OS, OSV) {
    if (OSV.value != "") {
        var OSVT = OSV.value.split(",");

        for (var i = 0; i < OSVT.length; i++) {
           if (OSVT[i] == pText)
              return true;
        }
    }

    return false;
}

// var_sc_optionsetvalue >> Provide schema-name for field which will
//                          store the multi selected values for Option Set
// OS >> Provide Option Set field object
// Save the selected text, this field can also be used in Advanced Find
function OnSave(OS, var_sc_optionsetvalue) {
    var getInput = OS.nextSibling.getElementsByTagName("input");
    var result = "";

    for (var i = 0; i < getInput.length; i++) {
        if (getInput[i].checked) {
            result += getInput[i].nextSibling.innerHTML + ",";
        }
    }

    //save value
    control = Xrm.Page.getControl(var_sc_optionsetvalue);
    attribute = control.getAttribute();
    attribute.setValue(result);
}

function createTable(var_sc_optionsetvalue) {
    //get option set value
    var OptionValue = Xrm.Page.getAttribute(var_sc_optionsetvalue);
    var c_OptionValue = Xrm.Page.getControl(var_sc_optionsetvalue);
    var d_OptionValue = var_sc_optionsetvalue + "_d";

    if (OptionValue.getValue() != null) {

        c_OptionValue.setVisible(true);
        var OptionValueHtml = "<div style=\"overflow-y:auto;width:100%; min-height: 5em; max-height: 1000px;\">";

        OptionValueHtml += "<table style='width:100%;height: 100%;'>";
        var OptionValueV = OptionValue.getValue();

        var OptionValueT = OptionValueV.split(",");
        var cols = 0;
        for (var row = 0; row < OptionValueT.length - 1; row++) {
            OptionValueHtml += "<tr  style='height:20px;'>";
            for (var i = cols; i < cols + 3; i++) {
                OptionValueHtml += "<td style='width:33%;'>";
                if (OptionValueT[i] != null || OptionValueT[i] != undefined) {

                    OptionValueHtml += OptionValueT[i];
                }
                OptionValueHtml += "</td>";
            }
            cols = cols + 3;
            OptionValueHtml += "</tr>";
            if (cols >= OptionValueT.length) {
                break;
            }
        }

        OptionValueHtml += "</table>";
        OptionValueHtml += "</div>";
        document.getElementById(d_OptionValue).innerHTML = OptionValueHtml;
    }
    else {
        c_OptionValue.setVisible(false);
    }
}

Get files of last hour in Azure Data Factory

  Case I have a Data Factory pipeline that should run each hour and collect all new files added to the data lake since the last run. What is...