Wednesday 19 December 2012

Create Custom view and Display in Sub Grid

Display Ur Custom View in SubGrid Control using Fetch XML


function updateSubGrid() {

    //This will get the grid details and store in a variable.

    var relatedProjects = document.getElementById("ProjectHR");



    //Initializing the lookup field to store in an array.

    var lookupfield = new Array;



    //Get the lookup field

    lookupfield = Xrm.Page.getAttribute("bis_project01").getValue();



    //This will get the lookup field guid if there is value present in the lookup

    if (lookupfield != null) {

        var lookupid = lookupfield[0].id;

    }

    //Else the function will return and no code will be executed.

    else {

        return;

    }



    //This method is to ensure that grid is loaded before processing.

    if (relatedProjects == null || relatedProjects.readyState != "complete") {



        //This statement is used to wait for 2 seconds and recall the function until the grid is loaded.

        setTimeout('updateSubGrid()', 2000);

        return;

    }

    //This is the fetch xml code which will retrieve all the consultants (resdex) related to the project selected for billing.

    var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>";

    fetchXml += "<entity name='new_resources'>";

    fetchXml += "<attribute name='new_name' />";

    fetchXml += "<attribute name='new_expectedctclakhs' />";

    fetchXml += "<attribute name='new_currentctc_lakhs' />";

    fetchXml += "<attribute name='new_rate' />";

    fetchXml += "<attribute name='new_resourcesid' />";

    fetchXml += "<order attribute='new_name' descending='false' />";

    fetchXml += "<link-entity name='new_projectstatus' from='new_consultant' to='new_resourcesid' alias='aa'>";

    fetchXml += "<filter type='and'>";

    fetchXml += "<condition attribute='new_exampleprojectid' operator='eq' uitype='opportunity' value='" + lookupid + "' />";

    fetchXml += "</filter>";

    fetchXml += "</link-entity>";

    fetchXml += "</entity>";

    fetchXml += "</fetch>";



    //Setting the fetch xml to the sub grid.

    relatedProjects.control.setParameter("fetchXml", fetchXml);



    //This statement will refresh the sub grid after making all modifications.

    relatedProjects.control.refresh();

}  

Wednesday 5 December 2012

Filterred Lookup in MSCRM 2011

Hi Folks,

Filttered Lookup in MSCRM 2011

function ChangeLookupView_Customer() {
//Note: in the form designer make sure the lookup field is set to

//"Show all views" in its "View Selector" property 

//Set parameters values needed for the creation of a new lookup view...

// Your new lookup views needs a unique id.  It must be a GUID.  Here I use the GUID of the current record.
var viewId = Xrm.Page.data.entity.getId();     
// The entity your new lookup view relates to
var entityName = "account";
// A name for new lookup view                   
var viewDisplayName = "Account - Customers";
// Whether your new lookup view should be the default view displayed in the lookup or not
var viewIsDefault = true;                      
   
//Define the Fetch XML query your new lookup view will use.  You can create this via Advanced Find.  You'll need to massage the syntax a little though
var fetchXml = 
              "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
              "<entity name='account'>" +
              "<attribute name='name' />" +
              "<attribute name='accountid' />" +
              "<attribute name='customertypecode' />" +
              "<filter type='and'>" +
              "<condition attribute='customertypecode' operator='eq' value='3' />" +
              "</filter>" +
              "<order attribute='name' decending='false' />" +
              "</entity>" +
              "</fetch>";

//Define the appearance of your new lookup view
    var layoutXml = 
                    "<grid name='resultset' object='1' jump='name' select='1' icon='1' preview='1'>" +  
                    "<row name='result' id='accountid'>" + 
// id = the GUID field from your view that the lookup should return to the CRM form
                    "<cell name='name' width='200' />" +  
                    "<cell name='customertypecode' width='200' />" +
                    "</row>" +
                    "</grid>";

    //Add your new view to the Lookup's set of availabe views and make it the default view
Xrm.Page.getControl("new_customer").addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, viewIsDefault);
}


function ChangeLookupView_Supplier() {

//Set parameters values needed for the creation of a new lookup view...
    var viewId = Xrm.Page.data.entity.getId(); 
// Using the same GUID, the viewId only has to be unique within each lookup's set of views
    var entityName = "account";
    var viewDisplayName = "Account - Suppliers";
    var viewIsDefault = true;

    //Define the Fetch XML query your new lookup view will use  
    var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
          "<entity name='account'>" +
          "<attribute name='name' />" +
          "<attribute name='accountid' />" +
          "<attribute name='customertypecode' />" +
          "<filter type='and'>" +
// A different value provided here to produce a different result set
          "<condition attribute='customertypecode' operator='eq' value='10' />" +  
          "</filter>" +
          "<order attribute='name' decending='false' />" +
          "</entity>" +
          "</fetch>";

    //Define the appearance of your new lookup view
    //No changes required here compared to the above, the lookups should have the same appearance
    var layoutXml = "<grid name='resultset' object='1' jump='name' select='1' icon='1' preview='1'>" +  
             "<row name='result' id='accountid'>" +
              "<cell name='name' width='200' />" +
              "<cell name='customertypecode' width='200' />" +
             "</row>" +
            "</grid>";

    //Add your new view to the Lookup's set of availabe views and make it the default view
    //The supplier field is specified here, we want to add this view to that lookup field
 Xrm.Page.getControl("new_supplier").addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, viewIsDefault);
}


 
Thanks to Gareth Tucker 
Hi Folks,

Scenario: I have an Account Entity where , my customer requirement is to view all the Emails to be displayed in a grid on selection of Account from the Lookup.
Solution:
1.Create a Javascript webresource with the following Code

function loadActivity()
{
 //get selected value from the Account lookup
var lookupItem = new Array;
lookupItem = Xrm.Page.getAttribute(CRMFieldSchemaName).getValue();
if (lookupItem[0] != null)

{

var id=lookupItem[0].id;

}

var viewDisplayName = "Test View"; // Custom name for the lookup window
//Get the fetch XML using Advance Find available in MSCRM 2011

var fetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
  <entity name='activitypointer'>
    <attribute name='activitytypecode"'/>
    <attribute name='subject'/>
    <attribute name='statecode'/>
    <attribute name='prioritycode'/>
    <attribute name='modifiedon'/>
    <attribute name='activityid'/>
    <attribute name='instancetypecode'/>
    <order attribute='modifiedon' descending='false'/>
    <filter type="and">
      <condition attribute='regardingobjectid' operator='eq' uitype='opportunity' value='+id+' />
    </filter>
  </entity>
</fetch>";

//Create a view that needs to be displayed in the grid
var layoutXML = "<grid name='resultset' object='1' jump='new_primary' select='1' icon='1' preview='1'>";
layoutXML += "<row name='result' id='new_name'>";
layoutXML += "<cell name='new_code' width='150' />";
layoutXML += "</row>";
layoutXML += "</grid>";
//Set the View created to the Grid Control

 Xrm.Page.getControl("Grid Namel").addCustomView(viewId, entityName, viewDisplayName, fetchXML , layoutXML, true);


}

Manipulate Data while importing data to CRM


Hi Folks,
Scenario: When i import excel sheet i have a field in that excel sheet called "employeid" once i import based on that employeeid some record should populate from another entity .
 I have an entity called "Payroll" to which i import data from excel sheet, in that it consists only employeeId. Ther is one more entity called "Employee" which has fields(EmployeeId, CTC).
Now when i import data to "Payroll"entity the CTC should be taken from "Employee"entity based n the employee id and set it in a new field of"Payroll" entity.
Fileds
EmployeeId -text field
CTC - Currency field


Workaround:
Steps:
1)Create a plugin with below code

If (entity.Attributes.Contains("employeeId"))
                {
                    //decimal actualCtc;
                    ConditionExpression condition = new ConditionExpression();
                    condition.AttributeName = "EmployeeId";
                    condition.Operator = ConditionOperator.Equal;
                    condition.Values.Add("employeeId");
                    FilterExpression filter = new FilterExpression();
                    filter.Conditions.Add(condition);

                    QueryExpression query = new QueryExpression("Employee");
                    query.ColumnSet.AddColumns("CTC ");
                    query.Criteria.AddFilter(filter);
                    EntityCollection _queryresult = service.RetrieveMultiple(query);

                    foreach (Entity employeeEntity in _queryresult.Entities)
                    {

                        Money ctc =  (Money)employeeEntity.Attributes["ctc"];
                        actualCtc = ctc.Value;
                    }
                    entity.Attributes["Payroll_CTC"] = new Money(actualCtc);
                    service.Update(entity);
                 
                }

2) Register the Plugin on create message of that entity to which the data is been imported
3)Import Data to CRM
4)Record would be created with CTC fetched from the other entity.

Plugin to generate word documetn using CRM data and Add that as an Attachment to that record

Hi all,
I hope this post will be helpful who would like to generate a word document using CRM data of a record and add that as an attachment  to that record.
Example Scenario : I have an Employee Entity, where i need to generate payslip for that employee on click of a button inside the form:
Steps to be followed:(In Form)
1. Create an Entity with the name"Employee" and add fields which are required:
2. Add a field of datatype "Two Option" and make visiblity of field as hidden
3. Create a web Resource/Javascript and write the function below in the web resource
//Function to change the Two Option Field value on a button CLick
function changeValue()
{
var value=Xrm.Page.getAttribute("FiledNAme").getValue();
 //Check the option fields value if it is yes/no (1/0)
if(value==0)
{
//set value to 1
Xrm.Page.getAttribute("FieldName").setValue(1);
 //Save the updated value
Xrm.Page.data.entity.save();
}
4.Publish ur webresource
5.Add a custom button in form using RibbonWorkBench tool and call ur JavaScript function on that button click: Follow the link to add custom button and call Javascript function
http://www.develop1.net/public/page/Ribbon-Workbench-for-Dynamics-CRM-2011.aspx

6.Create a C# plugin with the below code:

 using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Net;
using System.IO;
using HtmlAgilityPack;
using mshtml;
using System.Runtime.Serialization;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using NotesFor.HtmlToOpenXml;

namespace payslip
{
    public class MyPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // TODO - If you require tracing, uncomment the following line
            // ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            Entity entity = null;

            // Check if the InputParameters property bag contains a target
            // of the current operation and that target is of type DynamicEntity.
            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {
                // Obtain the target business entity from the input parmameters.
                entity = (Entity)context.InputParameters["Target"];

                // TODO Test for an entity type and message supported by your plug-in.
                if (context.PrimaryEntityName != "UR ENTITY NAME") { return; }
                if (context.MessageName != "Update") { return; }
            }
            else
            {
                return;
            }

            try
            {
                string invoice_number = "";
                DateTime joining_date;
                string consultant_name = "";
                string ctc_offered = "";
                string billable_amount = "";
                string tax_amount = "";
                string total_amount = "";
                DateTime invoice_date;
                string j_date = "";
                string i_date = "";
                string tax_per = "";



                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//Retrieve field from ur entity
                Entity receivableEntity = service.Retrieve("new_receivable", entity.Id, new ColumnSet("new_nameoftheconsultant", "new_dateofjoining", "new_ctcoffered", "new_billamount", "new_taxamount", "new_totalamount", "new_invoicenumber", "new_invoicedate", "new_generateinvoice", "new_accountname", "new_projectname", "new_projecttype","new_taxesapplicable"));
               
EntityReference proj = (EntityReference)receivableEntity.Attributes["new_projectname"];
                string projname = proj.Name;
                EntityReference acc = (EntityReference)receivableEntity.Attributes["new_accountname"];
                string name = acc.Name;
                string add = "";
                string city = "";
                string amttot = "";

                Guid id = acc.Id;
                //string ret = receivableEntity.Attributes["new_accountname"].ToString();
                QueryExpression q = new QueryExpression("account");
                q.ColumnSet = new ColumnSet(new string[] { "new_companyaddress_test", "address2_city", "name" });
                q.Criteria.AddCondition("name", ConditionOperator.Equal, name);
                EntityCollection qu = (EntityCollection)service.RetrieveMultiple(q);
                if (qu != null && qu.Entities.Count > 0)
                {
                    Entity ent = null;
                    for (int i = 0; i < qu.Entities.Count; i++)
                    {
                        ent = qu.Entities[i];
                        add = ent.Attributes["new_companyaddress_test"].ToString();
                        city = ent.Attributes["address2_city"].ToString();
                    }
                }
               
                string a = receivableEntity.Attributes["new_generateinvoice"].ToString();
                //string projectType = receivableEntity.Attributes["new_projecttype"].ToString();
               
                if (receivableEntity.Attributes.Contains("new_generateinvoice") && a == "True")
                {
                    if (receivableEntity != null)
                    {
                        if (receivableEntity.Attributes.Contains("new_nameoftheconsultant"))
                        {
                            consultant_name = (string)receivableEntity.Attributes["new_nameoftheconsultant"];

                        }
                        if (receivableEntity.Attributes.Contains("new_taxesapplicable"))
                        {
                            tax_per = (string)receivableEntity.Attributes["new_taxesapplicable"];

                        }
                        if (receivableEntity.Attributes.Contains("new_dateofjoining"))
                        {
                            joining_date = (DateTime)receivableEntity.Attributes["new_dateofjoining"];
                            j_date = joining_date.ToShortDateString();


                        }
                        if (receivableEntity.Attributes.Contains("new_ctcoffered"))
                        {
                            //ctc_offered = (float)receivableEntity.Attributes["new_ctcoffered"];

                            //ctc_offered = Convert.ToInt32(receivableEntity.Attributes["new_ctcoffered"]);
                            ctc_offered = ((Money)receivableEntity.Attributes["new_ctcoffered"]).Value.ToString();

                        }
                        if (receivableEntity.Attributes.Contains("new_billamount"))
                        {
                            billable_amount = ((Money)receivableEntity.Attributes["new_billamount"]).Value.ToString();

                        }
                        if (receivableEntity.Attributes.Contains("new_taxamount"))
                        {
                            tax_amount = ((Money)receivableEntity.Attributes["new_taxamount"]).Value.ToString();

                        }
                        if (receivableEntity.Attributes.Contains("new_totalamount"))
                        {
                            total_amount = ((Money)receivableEntity.Attributes["new_totalamount"]).Value.ToString();
                            decimal rev = ((Money)receivableEntity.Attributes["new_totalamount"]).Value;

                            int intvalue = Convert.ToInt32(rev);
                            amttot=NumberToWords(intvalue);
                        }
                        if (receivableEntity.Attributes.Contains("new_invoicenumber"))
                        {
                            invoice_number = (string)receivableEntity.Attributes["new_invoicenumber"];

                        }
                        if (receivableEntity.Attributes.Contains("new_invoicedate"))
                        {
                            invoice_date = (DateTime)receivableEntity.Attributes["new_invoicedate"];
                            i_date = invoice_date.ToShortDateString();

                        }
//Create a format in HTML format how u wanted in ur word document
                        string docbody = "<html><body><h3><b><center>                                                                                     INVOICE</center></b></h3><p><h3><pre><span>To,      " + name + "<br/>         " + add + "<br/>" + city + "</br>" + "                            <br/> Invoice No:" + invoice_number + "                    Date:  " + i_date + "      </span></pre></h3><table border=2 style='width: 40000px; height: 200px;' >     <tr style='border-width: 2px;' >         <td colspan='5'><center>              Recruitment Charges towards Placement of <b>" + projname + "</b></center></td>     </tr>     <tr style='width: 500px; height: 30px;'>         <td style='width: 40px;'><center>SL.No</center></td>        <td style='width: 200px;'><center>Name of the candidate</center></td>         <td style='width: 200px;'><center>Date of Joining</center></td>         <td style='width: 200px;'><center>CTC offered(Rs)</center></td>         <td style='width: 200px;'><center>Billable Amount (in Rs.)</center></td>     </tr>     <tr style='width: 800px; height: 50px;'>         <td style='width: 70px;' ><center>1</center></td>         <td>" + consultant_name + "</td>         <td>" + j_date + "</td>         <td>" + ctc_offered + "</td>         <td>" + billable_amount + "</td>     </tr>     <tr style='height: 20px;'>         <td colspan='4'><span style='margin-left: 600px;'>Amount         Rs.<span></td>         <td>" + billable_amount + "</td>     </tr>     <tr style='height: 20px;'>         <td colspan='4'><span style='margin-left: 600px;'>" + tax_per + "% Service Tax  Rs.<span></td>         <td>" + tax_amount + "</td>     </tr>     <tr style='height: 20px;'>         <td colspan='4'><span style='margin-left: 600px;'>TOTAL AMOUNT      Rs.<span></td>        <td>" + total_amount + "</td>     </tr>     <tr style='height: 20px;'>         <td colspan='5'><b>Rupees in words:</b> " + amttot + " only </td>     </tr> </table> <pre></body></html>";
     //Save ur document in Server                  
string f1 = @"C:\temp\" + consultant_name + ".docx";

                        using (MemoryStream generatedDocument = new MemoryStream())
                        {
                            using (WordprocessingDocument package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
                            {
                                MainDocumentPart mainPart = package.MainDocumentPart;
                                if (mainPart == null)
                                {
                                    mainPart = package.AddMainDocumentPart();
                                    new Document(new Body()).Save(mainPart);
                                }

                                HtmlConverter converter = new HtmlConverter(mainPart);
                                Body body = mainPart.Document.Body;

                                var paragraphs = converter.Parse(docbody);
                                for (int y = 0; y < paragraphs.Count; y++)
                                {
                                    body.Append(paragraphs[y]);
                                }

                                mainPart.Document.Save();
                            }
                            string w = entity.LogicalName;
                            File.WriteAllBytes(f1, generatedDocument.ToArray());
                            FileStream stream = File.OpenRead(f1);
                            byte[] byteData = new byte[stream.Length];
                            stream.Read(byteData, 0, byteData.Length);
                            stream.Close();
                            string encodedData = System.Convert.ToBase64String(byteData);


                            string filename="LISPLIN-"+name+"-240-"+i_date+".doc";
                            // Add the generated document as an attachment to that record
                            Entity annotation = new Entity("annotation");
                            annotation.Attributes["subject"] = "Invoice";
                            EntityReference noteref = new EntityReference();
                            noteref.LogicalName = entity.LogicalName;
                            noteref.Id = entity.Id;
                            annotation.Attributes.Add("objectid", noteref);
                            annotation.Attributes.Add("objecttypecode", w);
                            annotation.Attributes.Add("filename", filename);
                            annotation.Attributes.Add("mimetype", "application/ms-word");
                            annotation.Attributes.Add("documentbody", encodedData);
                            service.Create(annotation);



                        }
                    }
                }
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
            }
        }
//function to convert number to words(32 - thirty two)

        public static string NumberToWords(int number)
        {
            if (number == 0)
                return "zero";

            if (number < 0)
                return "minus " + NumberToWords(Math.Abs(number));

            string words = "";

            if ((number / 1000000) > 0)
            {
                words += NumberToWords(number / 1000000) + " Million ";
                number %= 1000000;
            }
            if ((number / 100000) > 0)
            {
                words += NumberToWords(number / 100000) + " Lakh ";
                number %= 100000;
            }

            if ((number / 1000) > 0)
            {
                words += NumberToWords(number / 1000) + " Thousand ";
                number %= 1000;
            }

            if ((number / 100) > 0)
            {
                words += NumberToWords(number / 100) + " Hundred ";
                number %= 100;
            }

            if (number > 0)
            {
                if (words != "")
                    words += "and ";

                var unitsMap = new[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" };
                var tensMap = new[] { "Zero", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };

                if (number < 20)
                    words += unitsMap[number];
                else
                {
                    words += tensMap[number / 10];
                    if ((number % 10) > 0)
                        words += "-" + unitsMap[number % 10];
                }
            }

            return words;
        }
    }


}


7. Add the required references and register the plugin for Update Message using Plugin Registration Tool
8. Now Refresh and go to ur entity open Record and Click on ur Custom button
9.Now the payslip would be generated and added as an attachment to that record








HOME PAGE GRID:
To perform the same operation for selected record from HomePage Grid Steps to be followed:
1) Create a custom button in Home Page Grid using RibbonWorkBench
2)Create a workflow which would change the Two Option Button activate the process as "As on Demand" process
3)Follow the post showing you how to trigger your workflow without writing a single line of code!
http://www.develop1.net/public/post/No-Code-Workflow-Shortcut-Ribbon-Button.aspx
4)And check ur entity attachments with generated payslip attached


Display Closed Activities Related to Account entity for selected record from HomePage grid MSCRM 2011

Hi,
Recently i had a requirement where my customer wanted ti view all the closed activity of an Account , which is available inside the record, but they wanted to have a view of that in HomePageGrid "Custom Button Click" . Workaround done are:
Steps:
1) Create a custom button in HomePageGrid and add CRMParameter "FirstSelectedItemId" , if u  r not familiar how to add button follow the below link which describes how to add button and paramters using RibbonWorkBench tool
http://www.develop1.net/public/page/Ribbon-Workbench-for-Dynamics-CRM-2011.aspx
2) Create a WebResource in ur CRM and add the below gicen Snippet code of JavaScript

function loadActivity(id)
{
//id returns with flower braces ("{,}") to remove that we use substring
var guid =id.substring(1,37)
//pass the id retrieved in ur function as a paramter to the url
var path1="http://SERVER URL/ORGNAME/userdefined/areas.aspx?navItemName=Closed%20Activities&oId=%7b"
var path2="%7d&oType=3&pagemode=iframe&security=852023&tabSet=areaActivityHistory"
var path3=path1+guid+path2;
//load the closed activity in a new window
window.open(path3,'',height=100,width=600,resizable=1)
 }

3) Call this javascript on ur button click (Follow Step 1)
4) Publish customisation
5) Select a record from HomePage Grid , u can view related closed activities of that Account


Hope it is helpful 



MSCRM 2011: Making Fields Searchable in an Entity

A Client recently asked, “How do I search by a custom field in an entity and have records returned in the view?” Not all fields in CRM are searchable by default. To make a field searchable you need to add it as a 'find column' to the entity's Quick Find View.

Let’s go through an example of this. Suppose there is a custom field on the Contact entity to designate the Parent Account for the Contact. We’d like to be able to search on that Parent Accoun field to find all those Contacts where a particular representative appears.

When you enter that value into the Contact search box and press enter I get the message that nothing is found. Why?

The reason that nothing is found is that the Parent Accoun field is not searchable by default. To make it searchable go to the Customize Entity option on the navigation ribbon. This will launch the customization screen where you can then choose the 'Views' option under the Contact entity.

Open the view whose type is 'Quick Find View' and select the 'Add Find Columns' option.

Put a check mark next to the Parent Account field so you can now search on it.

Add the field to the Quick Find View also by choosing ‘Add View Columns’ option and put a check mark next to the Account Representative field.

Publish your Customizations. You can now search on that field.