Month: October 2013

Code validation before upgrading to CRM 2013

Posted on

It is important to validate your current CRM system before upgrading to CRM 2013. Be sure, to run the CRM 2013 Custom Code Validation tool (available on codeplex)

http://www.microsoft.com/en-nz/download/details.aspx?id=30151

It will detect issues in the custom web resources that will no longer work after the upgrade is completed. The most common issues that this tool targets are –

  • CRM v4 client SDK calls
  • CRM 2007 end points
  • Common DOM manipulations

Running this tool before upgrade will enable you to identify issues and fix them prior to your scheduled upgrade so that your upgrade process can run smoothly.

Advertisements

13 Business Benefits of Dynamics CRM 2013

Posted on

Here I have highlighted the new features on offer and what benefits they will bring to businesses.

New user interface – The new user interface in CRM is clean and minimalistic. This should help staff be more productive and effective, using the latest form enhancements such as new layouts, replacement of the Ribbon with a minimalist command bar, auto-save, quick-create records, touch-friendly navigation, mapping integration, enterprise social integration and the reduced number of pop-ups.

Process Agility –The Process Agility feature can be used to model any number of business processes so that CRM is tailored specifically for your organisation. For example, new insurance policies versus insurance policy renewals, or a technical issue versus a customer complaint issue. At each stage, you can enforce that certain mandatory fields must be completed before staff can progress to the next stage. All of this functionality is available through an easy-to-use process modelling tool, reducing the dependency on custom development work.

Mobile Apps – The new mobile app allows access to CRM from a Windows 8 tablet or iPad. No additional training for the app is required as the reimagined interface, process agility and business rules are integrated seamlessly across web and mobile devices.

Server side synchronisation of Contacts, Tasks, Phone Calls and Appointments – Staff can directly synchronise information between CRM and Exchange using mobile devices to stay up-to-date at all times without the need for a third-party product or laptop. For example, staff will now see calendar appointments in their phone if they are scheduled to work on a service activity.

Enterprise social integration – Both CRM and non-CRM users can access key CRM information through Yammer. For example, businesses can automatically post to Yammer when an opportunity is opened with an existing customer. Using the Yammer app for mobile and tablet devices, staff can keep track of CRM and other enterprise wide conversations within the context of a social news feed.

Licensing changes – New licensing models offer more granular flexibility for how organisations license the staff who use CRM. Rather than having to purchase the same license for all users, organisations can now also purchase a lower cost license with reduced functionality to suit their staffing needs.

Business Rules – The Business Rules modeller will help reduce the total cost of ownership for your CRM solution. CRM 2013 allows you to tailor the user interface to your specific requirements through the Business Rules modeller. Instead of employing technical staff to build form validation by writing JavaScript code, rules can be modelled by business users in a simple-to-use interface to achieve the same result. Any rules that are defined using the Business Rules modeller will work across desktop and mobile devices.

Real time workflow – Workflows can be run in real-time so that changes to information are displayed instantly. For example, when submitting a Quote for approval the date and time the approval was sent can be updated and shown instantly to the user to confirm the approval was sent successfully. This functionality will reduce the need to write JavaScript and/or custom .NET plug-ins, thus reducing the total cost of ownership for the solution.

Inline editing of grids – Productivity will be improved by the ability to quickly and easily edit and update product information for opportunities, quotes, orders and invoices directly into the grid layout.

Click-to-call functionality – Lync or Skype click-to-call integration means staff can call customers directly from CRM. A phone call activity will automatically pop-up so that you can record the details of the call without having to click anywhere else in CRM. This will help with staff productivity and ensuring key information is being recorded in your CRM.

Access Teams – Businesses can quickly share and collaborate on CRM information outside of the standard security model using pre-defined Access Teams. For example, you can share an Opportunity record if the required products or services span multiple business units within your organisation. This ensures your security model is robust yet flexible at the same time.

Workflow Actions – Standard workflow actions can be combined to create powerful functionality for use in different areas of the application. For example, submission of an opportunity for approval can be created as a custom action using a combination of Update and Assign workflow actions. This custom action can then be called from another workflow, from the command bar via a Web Resource or externally via a web service call. This enables CRM to be integrated with other line-of-business applications more efficiently than before.

Staged upgrade path from CRM 2011 – For organisations moving from CRM 2011 to CRM 2013, there are a number of different upgrade paths to suit different change management and training requirements. Any supported customisations in CRM 2011 will have a supported upgrade path to CRM 2013.

Cheers

JScript Reference for CRM 2011

Posted on Updated on

Often CRM developers are looking for a quick reference guide for common Javascript requirements. Below I have added a comprehensive list of all the important Javascript functions.

1.  Get the GUID value of a lookup field: Note: this example reads and pops the GUID of the primary contact on the Account form

1
2
3
4
function AlertGUID() {
    var primaryContactGUID = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].id;
    alert(primaryContactGUID);
}

2.  Get the Text value of a lookup field: Note: this example reads and pops the name of the primary contact on the Account form

1
2
3
4
function AlertText() {
    var primaryContactName = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].name;
    alert(primaryContactName);
}

3.  Get the value of a text field: Note: this example reads and pops the value of the Main Phone (telephone1) field on the Account form

1
2
3
4
function AlertTextField() {
    var MainPhone = Xrm.Page.data.entity.attributes.get("telephone1").getValue();
    alert(MainPhone);
}

4.  Get the database value of an Option Set field: Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form

1
2
3
4
5
6
7
function AlertOptionSetDatabaseValue() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressTypeDisplayValue = AddressType.getValue();
    if (AddressTypeDisplayValue != null) {
        alert(AddressTypeDisplayValue);
    }
}

5.  Get the text value of an Option Set field: Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form

1
2
3
4
5
6
7
function AlertOptionSetDisplayValue() {
   var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressTypeDisplayValue = AddressType.getSelectedOption().text;
    if (AddressTypeDisplayValue != null) {
        alert(AddressTypeDisplayValue);
    }
}

6.  Get the database value of a Bit field:

1
2
3
4
// example GetBitValue("telephone1");
function GetBitValue(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

7.  Get the value of a Date field: returns a value like: Wed Nov 30 17:04:06 UTC+0800 2011 and reflects the users time zone set under personal options

1
2
3
4
// example GetDate("createdon");
function GetDate(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

8.  Get the day, month and year parts from a Date field:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// This function takes the fieldname of a date field as input and returns a DD-MM-YYYY value
// Note: the day, month and year variables are numbers
function FormatDate(fieldname) {
    var d = Xrm.Page.data.entity.attributes.get(fieldname).getValue();
    if (d != null) {
        var curr_date = d.getDate();
        var curr_month = d.getMonth();
        curr_month++;  // getMonth() considers Jan month 0, need to add 1
        var curr_year = d.getFullYear();
        return curr_date + "-" + curr_month + "-" + curr_year;
    }
    else return null;
}
// An example where the above function is called
alert(FormatDate("new_date2"));

9.  Set the value of a string field: Note: this example sets the Account Name field on the Account Form to “ABC”

1
2
3
4
function SetStringField() {
    var Name = Xrm.Page.data.entity.attributes.get("name");
    Name.setValue("ABC");
}

10.  Set the value of an Option Set (pick list) field: Note: this example sets the Address Type field on the Account Form to “Bill To”, which corresponds to a database value of “1”

1
2
3
4
function SetOptionSetField() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setValue(1);
}

11.  Set a Date field / Default a Date field to Today:

1
2
//set date field to now (works on date and date time fields)
Xrm.Page.data.entity.attributes.get("new_date1").setValue(new Date());

12.  Set a Date field to 7 days from now:

1
2
3
4
5
6
function SetDateField() {
    var today = new Date();
    var futureDate = new Date(today.setDate(today.getDate() + 7));
    Xrm.Page.data.entity.attributes.get("new_date2").setValue(futureDate);
    Xrm.Page.data.entity.attributes.get("new_date2").setSubmitMode("always"); // Save the Disabled Field
}

13.  Set the Time portion of a Date Field:

1
2
3
4
5
6
7
8
9
10
11
// This is a function you can call to set the time portion of a date field
function SetTime(attributeName, hour, minute) {
        var attribute = Xrm.Page.getAttribute(attributeName);
        if (attribute.getValue() == null) {
            attribute.setValue(new Date());
        }
        attribute.setValue(attribute.getValue().setHours(hour, minute, 0));
}
// Here's an example where I use the function to default the time to 8:30am
SetTime('new_date2', 8, 30);

14.  Set the value of a Lookup field: Note: here I am providing a reusable function…

1
2
3
4
5
6
7
8
9
10
11
// Set the value of a lookup field
function SetLookupValue(fieldName, id, name, entityType) {
    if (fieldName != null) {
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = id;
        lookupValue[0].name = name;
        lookupValue[0].entityType = entityType;
        Xrm.Page.getAttribute(fieldName).setValue(lookupValue);
    }
}

Here’s an example of how to call the function (I retrieve the details of one lookup field and then call the above function to populate another lookup field):

1
2
3
4
5
6
var ExistingCase = Xrm.Page.data.entity.attributes.get("new_existingcase");
if (ExistingCase.getValue() != null) {
    var ExistingCaseGUID = ExistingCase.getValue()[0].id;
    var ExistingCaseName = ExistingCase.getValue()[0].name;
    SetLookupValue("regardingobjectid", ExistingCaseGUID, ExistingCaseName, "incident");
}

15.  Split a Full Name into First Name and Last Name fields:

1
2
3
4
5
6
7
8
function PopulateNameFields() {
    var ContactName = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].name;
    var mySplitResult = ContactName.split(" ");
    var fName = mySplitResult[0];
    var lName = mySplitResult[1];
    Xrm.Page.data.entity.attributes.get("firstname").setValue(fName);
    Xrm.Page.data.entity.attributes.get("lastname").setValue(lName);
}

16.  Set the Requirement Level of a Field: Note: this example sets the requirement level of the Address Type field on the Account form to Required.  Note: setRequiredLevel(“none”) would make the field optional again.

1
2
3
4
function SetRequirementLevel() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setRequiredLevel("required");
}

17.  Disable a field:

1
2
3
4
function SetEnabledState() { 
    var AddressType = Xrm.Page.ui.controls.get("address1_addresstypecode"); 
    AddressType.setDisabled(true); 
}

18.  Force Submit the Save of a Disabled Field:

1
2
// Save the Disabled Field
Xrm.Page.data.entity.attributes.get("new_date1").setSubmitMode("always");

19.  Show/Hide a field:

1
2
3
4
function hideName() {
    var name = Xrm.Page.ui.controls.get("name");
    name.setVisible(false);
}

20.  Show/Hide a field based on a Bit field

1
2
3
4
5
6
7
8
9
function DisableExistingCustomerLookup() { 
   var ExistingCustomerBit = Xrm.Page.data.entity.attributes.get("new_existingcustomer").getValue();
    if (ExistingCustomerBit == false) {
       Xrm.Page.ui.controls.get("customerid").setVisible(false); 
    }
    else {
       Xrm.Page.ui.controls.get("customerid").setVisible(true); 
    }
}

21.  Show/Hide a nav item: Note: you need to refer to the nav id of the link, use F12 developer tools in IE to determine this

1
2
3
4
function hideContacts() {
    var objNavItem = Xrm.Page.ui.navigation.items.get("navContacts");
    objNavItem.setVisible(false);
}

22.  Show/Hide a Section: Note: Here I provide a function you can use.  Below the function is a sample.

1
2
3
4
5
6
7
8
function HideShowSection(tabName, sectionName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).sections.get(sectionName).setVisible(visible);
    }
    catch (err) { }
}
HideShowSection("general", "address", false);   // "false" = invisible

23.  Show/Hide a Tab: Note: Here I provide a function you can use. Below the function is a sample.

1
2
3
4
5
6
7
8
function HideShowTab(tabName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).setVisible(visible);
    }
    catch (err) { }
}
HideShowTab("general", false);   // "false" = invisible

24.  Save the form:

1
2
3
function SaveAndClose() {
    Xrm.Page.data.entity.save();
}

25.  Save and close the form:

1
2
3
function SaveAndClose() {
    Xrm.Page.data.entity.save("saveandclose");
}

26.  Close the form: Note: the user will be prompted for confirmation if unsaved changes exist

1
2
3
function Close() {
    Xrm.Page.ui.close();
}

27.  Determine which fields on the form are dirty:

1
2
3
4
5
6
7
8
9
var attributes = Xrm.Page.data.entity.attributes.get()
 for (var i in attributes)
 {
    var attribute = attributes[i];
    if (attribute.getIsDirty())
    {
      alert("attribute dirty: " + attribute.getName());
    }
 }

28.  Determine the Form Type: Note: Form type codes: Create (1), Update (2), Read Only (3), Disabled (4), Bulk Edit (6)

1
2
3
4
5
6
function AlertFormType() {
    var FormType = Xrm.Page.ui.getFormType();
     if (FormType != null) {
        alert(FormType);
    }
}

29.  Get the GUID of the current record:

1
2
3
4
5
6
function AlertGUID() {
    var GUIDvalue = Xrm.Page.data.entity.getId();
    if (GUIDvalue != null) {
        alert(GUIDvalue);
    }
}

30.  Get the GUID of the current user:

1
2
3
4
5
6
function AlertGUIDofCurrentUser() {
    var UserGUID = Xrm.Page.context.getUserId();
     if (UserGUID != null) {
        alert(UserGUID);
    }
}

31.  Get the Security Roles of the current user: (returns an array of GUIDs, note: my example reveals the first value in the array only)

1
2
3
function AlertRoles() {
    alert(Xrm.Page.context.getUserRoles());
}

32.  Determine the CRM server URL:

1
2
3
4
5
6
7
// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();
// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

33.  Refresh a Sub-Grid:

1
2
var targetgird = Xrm.Page.ui.controls.get("target_grid");
targetgird.refresh();

34.  Change the default entity in the lookup window of a Customer or Regarding field: Note: I am setting the customerid field’s lookup window to offer Contacts (entityid 2) by default (rather than Accounts). I have also hardcoded the GUID of the default view I wish displayed in the lookup window.

1
2
3
4
5
function ChangeLookup() {
    document.getElementById("customerid").setAttribute("defaulttype", "2");
    var ViewGUID= "A2D479C5-53E3-4C69-ADDD-802327E67A0D";
    Xrm.Page.getControl("customerid").setDefaultView(ViewGUID);
}

XrmServiceToolkit – Better way of consuming REST/SOAP services in CRM

Posted on

Recently I found another interesting tool for CRM.

XrmServiceToolkit is a JavaScript library which can be used for JavaScript Development under the platform for Microsoft Dynamics CRM 2011/2013 environments. The library contains four major parts regarding functions.

Common: General Methods used for various purpose.
Rest: Organization Data Service functions including CRUD, Associate, Disassociate, etc
Soap: Organization Service functions including CRUD, Fetch, Associate, Disassociate, etc
Extension: jQuery extension to utilize WebResource to extend CRM 2011 / CRM 2013 including dependent OptionSet, field tooltip, add custom filter view to lookup field. (Some Methods ‘Unsupported’)

Download link to codeplex – http://xrmservicetoolkit.codeplex.com/

How to use it in CRM – 

1. Add a reference to the XrmServiceToolkit.js file on your CRM form

2. Add a reference to JQuery 1.7.1 or above on your CRM form

3. Add json reference on your CRM form

4. Thats all!

Refer to the documentation section on codeplex for usage samples.

Read only user in CRM

Posted on Updated on

To create a read only user in CRM –

1. Create a new Business Unit “Read Only” with root BU as the parent BU

2. Create a new Security role “Read Only” with only Read permissions on all the entities in the system.

3. Assign the Read Only role to “Read Only” team.

4. Change the BU of the Read Only user to “Read Only” BU.

Hope it helps.

Cheers

Custom tooltip in CRM 2011

Posted on

Hi,

Out of the box CRM doesn’t allow you to setup a custom tooltip. To add a custom tooltip in CRM.

1. Add following javascript on the form –

 

AddressValidator

replace crmfieldscehmaname with the actual schema name. (this is case sensitive)

2. Add following method

AddressValidator

3. Add following method

AddressValidator

 

4. Call the Addtooltip method method on load of the form. Pass the control id and the tooltip text.

Hope it helps.

Cheers

 

 

Changing the Customer lookup on case entity from Account to Contact in CRM 2011

Posted on

Hi,

By default the customer lookup on Case entity in CRM 2011 always points to Account. This can be changed to point to Contact or a different view in CRM with the help of a small javascript.

OnLoad of Case form call following code –

AddressValidator

Change the Guid of the view you want to use. Please note, the value of the Guid will change for every environment / organisation.