Archive

Posts Tagged ‘CRM 2016’

Retrieve and Update record with alternate key using Web API – CRM 2016

July 1, 2016 1 comment

Alternative Keys are useful to retrieve or update the records without the need of GUID. It avoids the overhead of retrieving record’s GUID while update operation.

In conventional way, to update an Account record from external web application, you would need to get the GUID first and then update.

With alternate key, you can configure any of your field of type (Single Line of Text, Whole Number or Decimal Number) as Alternate key and use instead of GUID to retrieve or update.

We can have up to 5 different alternate keys per entity.

Sample C# code to update record with out GUID:

  • I configured “Account Number” as alternate key.
  • I have an Account with ‘Account Number’ as ‘Acct123’ and below is the code to update record. Notice that I did not provide the record GUID.

Entity account = new Entity(“account”, “accountnumber”, “Acct123”);
account[“name”] = “Rajeev Modified”;
service.Update(account);

Create an Alternate key

  • Go to Customization–> Entity–> Keys –> New
Create Alternate Key

Create Alternate Key

  • Click “Ok”
  • Wait for few seconds so that the background workflow complete creation of required indexes.

Jscript to retrieve using Alternate key:

  • Below is the script to retrieve a record with alternate key using web api.

function getAccountByAlternateKey() {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
// Account Number as an ‘Alternate key’
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/accounts(accountnumber=’Acct123′)“), true);
// If multiple keys as ‘Alternate key’
//req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/accounts(name=’Rajeev’,emailaddress1=’rajeev@live.com’)”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response);
var dat = data.value;
for (var i = 0; i < dat.length; i++) {
var accountId = dat[i].accountid;
Xrm.Utility.alertDialog(“Account Id : ” + accountId);
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error retrieving Account- ” + error.message);
}
}
};

req.send();
} catch (e) {
alert(“Error in getAccountByAlternateKey – ” + e.description);
}
}

JScript to Update Record Using Alternate Key

function updateAccountByAlternateKey() {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
// Account Number as an ‘Alternate key’
req.open(“PATCH“, encodeURI(clientUrl + “/api/data/v8.0/accounts(accountnumber=’Acct123′)“), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
var accountUri = this.getResponseHeader(“OData-EntityId”);

//get EntityId from ResponseHeader of Created Record
var accountID = accountUri.split(/[()]/);
accountID = accountID[1];

Xrm.Utility.alertDialog(“Updated Account ID : ” + accountID);
}
}
};

// Set Account Object
var objAccount = {};
objAccount.name = “Rajeev Modified”;
objAccount.revenue = 123456;

//convert JSON object to string
var body = JSON.stringify(objAccount);

req.send(body);
} catch (e) {
alert(“Error in updateAccountByAlternateKey – ” + e.description);
}
}

Refer article  for more details.

🙂

Advertisement
Categories: CRM 2016 Tags: , ,

JScript to Create record and its related record using Web API – CRM 2016

Below is the script snippet to create ‘Account’ record using Web API.

function createAccount() {
var clientUrl = Xrm.Page.context.getClientUrl();

var req = new XMLHttpRequest()
req.open(“POST”, encodeURI(clientUrl + “/api/data/v8.0/accounts”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.setRequestHeader(“Prefer”, “odata.include-annotations=*”);

// Set Account Object
var objAccount = {};
objAccount.name = “Rajeev Associates”;
objAccount.creditonhold = false;
objAccount.accountcategorycode = 1;
objAccount.revenue = 123456;

// Create new Contact and Set as ‘Primary Contact’
objAccount.primarycontactid = {};
objAccount.primarycontactid.firstname = “Hello”;
objAccount.primarycontactid.lastname = “Lobo”;

// Set existing Contact as ‘Primary Contact’
//objAccount[‘primarycontactid@odata.bind’] = “/contacts(” + { contact GUID } + “)”;

//convert JSON object to string

var body = JSON.stringify(objAccount);

req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
var accountUri = this.getResponseHeader(“OData-EntityId”);

// Get Account GUID
var accountID = accountUri.split(/[()]/);
accountID = accountID[1];

Xrm.Utility.alertDialog(“Created Account ID : ” + accountID);
}
}
};

req.send(body);
}

  • To set the lookup you need to fetch the Contact GUID first and set to ‘primarycontactid@odata.bind’. ‘@odata.bind’ is suffix and ‘primarycontactid‘ is the schema name of lookup.
  • Below is sample script to retrieve Contact GUID by Fullname

function getPrimaryContact() {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/contacts?$select=fullname&$filter=fullname eq ‘John Miller'”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response);
var dat = data.value;

// Loop through ‘Contact’ result set
for (var i = 0; i < dat.length; i++) {

// Get ‘Contact ID’ from Contact record.
var contactId = dat[i].contactid;
if (contactId) {

Xrm.Utility.alertDialog(“Contact ID : ” + contactId);
}
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error retrieving contact – ” + error.message);
}
}
};

req.send();
}

🙂

Categories: CRM 2016 Tags: , , ,

JScript to retrieve and execute view (Predefined Query) using Web API – CRM 2016

Assume you would need to retrieve ‘Active Accounts’ from your script, you can either retrieve by building FetchXML from scratch or simply use Web API to execute existing ‘Active Accounts’ view query with no need of writing Fetch XML.

Using Web API we can retrieve and execute predefined queries (i.e., System view and Personal view queries).

Below are the steps to retrieve and execute ‘System view’ query using CRM WebAPI

  • Get the GUID of View by Name.
  • Execute the view and fetch the result set. (Columns of the result set would be same as ‘System View’ columns)

Script

function executeView(viewName) {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
// Get ‘Active Accounts’ GUID
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/savedqueries?$select=name,savedqueryid&$filter=name eq ‘” + viewName + “‘”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response);
var dat = data.value;
for (var i = 0; i < dat.length; i++) {
var viewId = dat[i].savedqueryid;
alert(“View Id : ” + viewId);
if (viewId) {
executeViewQuery(viewId);
}
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error while fetching view id” + error.message);
}
}

};
req.send();
} catch (e) {
alert(“Error in getViewId” + e.description);
}
}

 

function executeViewQuery(viewId) {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest()
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/accounts?savedQuery=” + viewId + “”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
// Include this to get Lookup and Optionset text
req.setRequestHeader(“Prefer”, “odata.include-annotations=OData.Community.Display.V1.FormattedValue”);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response);
var dat = data.value;
for (var i = 0; i < dat.length; i++) {
alert(“Account Name – ” + dat[i].name);
// Read Lookup name (i.e.,Primary Contact)
alert(“Primary Contact – ” + dat[i][‘_primarycontactid_value@OData.Community.Display.V1.FormattedValue’]);
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error while executing view query” + error.message);
}
}
};
req.send();
} catch (e) {
alert(“Error in getViewId” + e.description);
}
}

The result set would look as below.

Execute Query Using WebAPI

How Do I call this method:

  • Copy and paste above two functions.
  • Pass the ‘System View’ name to executeView({View Name}) function.

// To Retrieve and Execute ‘Active Accounts’ view

executeView(“Active Accounts”);

Note: To use “Personal View”, change the “savedqueries” to “userqueries” in Wab API URI.

Refer MSDN Article for more details.

🙂

Switch Business Process Flow using Jscript based on CRM form’s field value

April 30, 2016 1 comment

Recently we got a requirement to switch the Business process on Case form based on ‘Case Origin’.

Its easily achievable using Jscript “setActiveProcess” method.

Xrm.Page.data.process.setActiveProcess(processId, callbackFunction);

  • processId‘ is the GUID of the ‘Business Process Flow’. You can copy the GUID from URL.
  • Go to ‘Settings –> Processes’ open the ‘Business Process Flow’ and copy the value from ‘id’ parameter, between %7b %7d
Copy Business Process ID

Copy Business Process ID

  • ‘callbackFunction’ is your custom JScript function name which gets triggered post ‘Business Process’ switch.

Below are the scenario and steps.

  • I have 3 Active Business Process Flows on my ‘Case’ entity.
Active Business Process Flows

Active Business Process Flows

  • ‘Business Process Flows’ are Security Role Based, so if my user has access to all 3 ‘Business Process Flows’, he can switch the process using ‘Switch Process’option.
Swicth Business Process

Swicth Business Process

Multiple Business Process Flows

Multiple Business Process Flows

  • In my scenario, ’Switch Process’ should happen based on ‘Case Origin’ field.
    • If ‘Case Origin’= Phone; Set “Business Process1”
    • If ‘Case Origin’= Email; Set “Business Process2”
  • Below is the script

function onload() {
// If not new Case form
if (Xrm.Page.ui.getFormType() != 1) {
// Read Origin Option text
var origin = Xrm.Page.data.entity.attributes.get(“caseorigincode”);

if (origin && origin.getText()) {
var caseOrigin = origin.getText();

// Get Business process flow id
var processFlow1Id = “6CD44946-0DC5-47E3-9B62-6D7309254710”;
var processFlow2Id = “0B3A94CD-CD43-4F49-A9A3-93C4AC684CFA”;

// Get Current Active Process Id
var activeProcess = Xrm.Page.data.process.getActiveProcess();
var currProcessId = activeProcess.getId();

if (caseOrigin.toLowerCase() == “phone”) {
// Change the process only if current Active Process not the Target one
if (currProcessId.toLowerCase() != processFlow1Id.toLowerCase()) {
// Switch to the “Process Flow 1”
Xrm.Page.data.process.setActiveProcess(processFlow1Id, myCallBack);
}
} else if (caseOrigin.toLowerCase() == “email”) {
// Change the process only if current Active Process not the Target one
if (currProcessId.toLowerCase() != processFlow2Id.toLowerCase()) {
// Switch to the “Process Flow 2”
Xrm.Page.data.process.setActiveProcess(processFlow2Id, myCallBack);
}
}
}
}
}

// Call back function post Process flow switch
function myCallBack(response) {
if (response == “success”) {
alert(“BPF changed !!!”);
// Save the form
Xrm.Page.data.entity.save();
}
else {
alert(“Error changing BPF!!!”);
}
}

How do I use the script?

  • Copy the script and create a new ‘Web resource’ in CRM and add to ‘Case’ form.
  • Register ‘onload()’ function on form onload event.
Register onload event - Case form

Register onload event – Case form

  • Publish the Customizations.
  • Open the Case record and based on ‘Case origin’ system auto switches to the Business process Flow.
New Business Process Selected

New Business Process Selected

Key points on multiple ‘Business process flows’:

  • You can have up to 10 active business process flows per entity.
  • You can associate business process flows with security roles so that only people with those security roles can see or use them.
  • In case of multiple Active ‘Business process flows’, the first activated business process flow in that list is the one that will be applied by default.
  • Each record can have only one business process flow at a time.
  • If someone’s security roles do not allow them to use a specific business process flow, the current business process flow will be visible, but disabled.

🙂

Build Auto Complete Text Box using Jscript – CRM 2016

In CRM 2016, we got showAutoComplete and hideAutoComplete methods to configure the auto-completion experience in text controls in forms.

In this article, I am going to configure “Auto Complete” feature for my “Locality” text box on my Account form.

Auto Complete Localities

Auto Complete Localities

JScript:

function suggestLocality() {
// List of sample Locality names to suggest
accounts = [
{ name: ‘AA Street’, code: ‘A01’ },
{ name: ‘AB Street’, code: ‘A02’ },
{ name: ‘AC Street’, code: ‘A03’ },
{ name: ‘Benetten street’, code: ‘A04’ },
{ name: ‘Beverly Hills’, code: ‘A05’ },
{ name: ‘City Street’, code: ‘A06’ },
{ name: ‘City Power & Light’, code: ‘A07’ },
{ name: ‘Aruna Street’, code: ‘A08’ },
{ name: ‘Winery Street’, code: ‘A09’ },
{ name: ‘Coho Vineyard & Winery’, code: ‘A10’ },
{ name: ‘Zeebra Street.’, code: ‘A11’ }
];

var localityKeyPress = function (ext) {
try {
var userInput = Xrm.Page.getControl(“raj_locality”).getValue();
resultSet = {
results: new Array(),
commands: {
id: “sp_commands”,
label: “Explore CRM”, // Help link text
action: function () {
window.open(“http://rajeevpentyala.com&#8221;); // Help link URL
}
}
};

// Read the ‘Text’ entered in Locality field.
var userInputLowerCase = userInput.toLowerCase();
for (i = 0; i < localities.length; i++) {
if (userInputLowerCase === localities[i].name.substring(0, userInputLowerCase.length).toLowerCase()) {
resultSet.results.push({
id: i,
fields: [accounts[i].name]
//, icon:<url> — Its an option field. You can show icon next to the Auto populated text.
});
}
if (resultSet.results.length >= 10) break;
}

if (resultSet.results.length > 0) {
// If matches found; Show the Auto complete text area with matched localitites (i.e., Up to 10)
ext.getEventSource().showAutoComplete(resultSet);
} else {
// If no match found; Hide the Auto complete text area.
ext.getEventSource().hideAutoComplete();
}
} catch (e) {
alert(“Error while auto complete – ” + e.description);
}
};

// Attach Key Press event to ‘Locality’ text box
Xrm.Page.getControl(“raj_locality”).addOnKeyPress(localityKeyPress);
}

How do I use it:

  • Copy the “suggestLocality” function and create a web resource in CRM.
  • Register the “suggestLocality” function on onload event of Account form.
Auto Complete Onload Event

Auto Complete Onload Event

  • Publish the Customization’s.
  • Open an Account and start typing in “Locality” text box.
Auto Complete Localities

Auto Complete Localities

  • You can extend the script by instead of hard coding Localities, you can read from any existing entity and populate the list.

Important Notes on Auto Complete feature:

  • “Auto Complete” show up to 10 matching strings in a drop-down list as users press keys to type character in a specific text field.
  • These methods aren’t supported for the CRM mobile clients (phones or tablets).

🙂

Categories: CRM 2016 Tags: , ,

Task Flow – CRM 2016

April 16, 2016 4 comments
  • “Task Flow” is a new feature available with CRM 2016 online update and is currently on preview mode.
  • Task flows are targeted for phones or tablets.
  • You can configure set of steps, where user perform day to day and package that as a ‘Task Flow’.
  • “Task Flows” are somewhat similar to Dialog, which helps User with guided navigation of common tasks, but for Phone and Tablets.

In this article I am going to create a simple ‘Task Flow’ to capture Contact’s address along with a ‘Business Rule’.

Enable the preview feature:

  • Task flows are a preview feature in CRM Online 2016 Update. So we need to first enable the feature.
  • Go to Settings -> Administration -> System Settings -> Preview
  • Agree the License terms and select the preview feature.
Enable Previews

Enable Previews

  • After enabling ‘Task Flow’ feature, you will get a new ‘Business Process Type’, if you choose ‘Business Process Flow’.
New Business Type

New Business Type

Create Task Flow

  • Go to Settings -> Processes -> New -> ‘Business Process Flow’
  • Select “Business Process Type”, “Run process as a task flow (Mobile only)”
  • I selected entity as “Contact”
  • I named my Task Flow as “Contact Address Capture Task”
Task Flow - Create a Task Flow

Task Flow – Create a Task Flow

Configure your ‘Task Flow’

  • As I want to capture my Contact’s Address details, I configured my ‘Task Flow’ with below fields.
Task Flow - Configure Fields To Be Captured

Task Flow – Configure Fields To Be Captured

Configure ‘Business Rule’

  • I want ‘Phone number’ mandatory, if my Contact does not specify ‘City’.
  • So I configured the Business Rule as below
Task Flow - Business Rules

Task Flow – Business Rules

Save and Activate.

Check the ‘Task Flow’ on Mobile client

  • Open the ‘Dynamics CRM Application’ on Mobile
Mobile-Welcome Screen

Mobile-Welcome Screen

  • You find an Icon on left corner, which shows all the available ‘Task Flows’
Task Flow Process Icon

Task Flow Process Icon

  • Click on the Icon and choose the “Contact Address Capture Task”.
Pick Task Flow

Pick Task Flow

  • Since “Task Flow” was configured on ‘Contact’ entity, I got ‘Contact’ search screen.
Search Contact

Search Contact

  • I picked up the Contact which i want to update the Address details.
  • It shows up the fields I configured along with ‘Business Rule’ (‘Phone’ become Required since ‘City’ is blank)
Configured Address Task Flow

Configured Address Task Flow

  • I provided the details and click ‘Done’ to save the details.
Capture the details

Capture the details

🙂

CRM 2016 – Voice of customer’s survey

March 31, 2016 5 comments

Capturing customer feedback is crucial in any Service industry to serve Customer better. In Dynamics CRM, Survey feature was the ask from many customers across the world. It has been addressed in the latest release of CRM 2016.

  • “Voice of the Customer survey” is a new feature which is in preview mode, currently available on CRM Online 2016 Update 0.1.
  • We can create and send out surveys to get feedback from your customers about your products or services.
  • We can capture and store the responses in CRM.
  • Respondents can take the surveys on a phone, tablet, or computer.

Below are steps to configure and use Survey feature.

Set up ‘Voice of customer’ in your CRM online

  • ‘Voice of customer’ feature comes as solution and need to be installed in CRM online instance.
  • Open ‘CRM Online Administration Center’ and click on ‘Solutions’
Available solutions

Voice Of The Customer – available solutions

  • From the available list choose ‘Voice of the customer’ solution and click ‘INSTALL’.
Install solution

Install solution

Accept the terms & conditions

  • After the Installation completes, open the CRM instance.
  • Open the solution and on configuration page ‘Accept the condition’ to start using Survey feature.
Agreement

Agreement

Configure Survey

  • After the solution installation, there will be a ‘Voice of the customer’ tab on sitemap.
Voice Of The Customer - Sitemap

Voice Of  The Customer – Sitemap

  • To configure a new ‘Survey’ click on ‘Voice of the Customer -> Surveys’
  • There is a pre-built ‘Default Survey Template’ available, where you can use or you can create a new Survey.
  • “Survey” form has all the details corresponding to the Survey right from Theme,Logo etc…
Survey Details

Survey Details

  • Every Survey record has 3 forms
    • Survey: Details of the Survey
    • Designer: Where we design the survey with question and answers
    • Dashboard: Reports
Survey forms

Survey forms

Design Survey

  • Open the ‘Default Survey Template’ and select “Designer” form.
Survey Designer

Survey Designer

  • Drag and drop the available controls to create the Survey.
  • In my sample, I created a “Diet Survey” with a question of type “Single Response” and “Rating” control.
  • Once the design complete, you can preview and Publish the Survey.
Survey Preview

Survey Preview

Send the Survey

  • Once you Publish the survey, CRM gives you a URL (Anonymous Survey), where it can be forwarded to Customers to capture their feedback.
Survey Invitations

Survey Invitations

  • Copy and open the URL from ‘Anonymous Link’ and complete the survey
Survey Capture

Survey Capture

Capture the Survey Response

  • Once Customer submitted the response, it will be stored as a record in “Survey Response”.
Survey Responses

Survey Responses

  • More details will be captured about survey in the ‘Survey Response ‘ record.
Survey Response Details

Survey Response Details

🙂

CRM 2016 Document Generation – Enable Developer Tab and Add repeated rows in word file

March 12, 2016 1 comment

Document Generation is a new feature introduced in CRM 2016. Document Generation simplifies converting your CRM data to either Word or Excel documents.

Below are the steps to

  • Download Template
  • Configure Template
  • Upload Template
  • Generate Document.

Download the Document Template

  • Navigate to ‘Settings  -> Templates’
  • Choose ‘Document Templates’
Create Document Template

Create Document Template

  • Click ‘New’ button
  • Choose the type of document (Excel\Word) and choose entity
New Template

New Template

  • Select the Related entities, if you want to populate your Document with data from related entities too. I chosen ‘Contact’ in this example.
Choose related entities

Choose related entities

  • Once you download the template you can open and create a template by mapping the fields from CRM.
  • But what if you don’t find the ‘Developer’ tab?
Document Template - No Developer Tab

Document Template – No Developer Tab

Steps to enable ‘Developer’ tab

  • Open the word document
  • Go to File -> Options -> Customize Ribbon
  • Select the ‘Developer’ option and click ‘Ok’
Download Template - Enable Developer tab

Download Template – Enable Developer tab

  • Once you get ‘Developer’ tab on Word document, choose ‘XML Mapping’ pane and choose “urn:microsoft-crm/…../{entity_name}/1/
XML Mapping Pane

XML Mapping Pane

Configure Document Template

  • In this example, I am going to configure a Document Template with Account details along with all associated Contacts.
  • To add Account Name choose ‘Name’ from ‘XML Mapping’ pane and right click and choose ‘Plain Text’.
Map Account Name

Map Account Name

  • If you have to display multiple rows (i.e., Contacts of an Account record) add a table and map fields from ‘Contact’.
Configure Document Template

Configure Document Template

Upload Document Template

  • Once you are done with content preparation, save the document and upload back to CRM using ‘UPLOAD TEMPLATE’.
Upload Template

Upload Template

  • I name my Document Template with ‘Account_Venilla’.
Save Document Template

Save Document Template

Configure Document Template - 4

  • We are done with configuring ‘Document Template’. Next step is generate the document from the Entity.
  • We can also upload ‘Document Template’ through SDK using ‘DocumentTemplate‘ class.

Document Generation

  • Open Account record
  • Select ‘Word Templates -> {Document_Template_Name}’
Document Generation

Document Generation

  • Download the document and open.
  • You would see some thing as below
Generated Document

Generated Document

🙂

CRM 2016 Web API – Impersonate User

January 1, 2016 3 comments

In CRM, Impersonation is possible in Plug-ins (using ‘Run As’ while registering Plug-in step) or using ‘CallerId’ property while instantiating OrganizationServiceProxy.

What if I have to impersonate ‘Retrive’ operation from Jscript? This was not possible.

With advent of CRM Web API with CRM 2016 we can impersonate in Jscript.

What is a Web API :

  • The Web API implements the OData (Open Data Protocol), version 4.0.
  • The new Web API provides better capabilities over the OData service introduced with CRM 2011 and OData service will be deprecating with this release.
  • It provides a modern, RESTful web service you can use to interact with data in CRM using a wide variety of platforms, programming languages and devices
  • The Web API will provide parity with the existing organization service (SOAP endpoint).
  • You can perform all operations using HTTP requests with the Web API located at [organization uri]/api/data/v8.0/

Impersonate another User using Web API:

  • To impersonate a user, add a request header named MSCRMCallerID with a GUID value equal to the impersonated user’s systemuserid before sending the request to the web service.

Sample Script with impersonation to create an Account Record

function createAccount() {
var clientURL = Xrm.Page.context.getClientUrl();
var impersonateUserId = “7eb682f1-ca75-e511-80d4-00155d2a68d1”;// GUID
var req = new XMLHttpRequest()
req.open(“POST”, encodeURI(clientURL + “/api/data/v8.0/accounts”), true);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
// Set the Caller ID; GUID of User
req.setRequestHeader(“MSCRMCallerID”, impersonateUserId);
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
var accountUri = this.getResponseHeader(“OData-EntityId”);
alert(“New account created; URI: ” + accountUri)
}
else {
var error = JSON.parse(this.response).error;
alert(“Error creating Account – ” + error.message);
}
}
};

// Set Account record properties
req.send(JSON.stringify({ name: “Rajeev Pentyala”, description: “Account created using Web API”, revenue: 5000000 }));
}

🙂

Categories: CRM, CRM 2016 Tags: , ,

CRM 2016 Web API – Optimistic Concurrency

December 31, 2015 1 comment

Assume a scenario, you retrieved an Account and wanted to update the ‘Name’ field. But due to concurrency the same Account has changed on the server since you retrieved it and you may not want to complete the update.

So how to detect this situation and avoid concurrency issues? The answer is ‘Optimistic Concurrency’ patterns provided by Web API.

What’s Optimistic Concurrency

  • Optimistic concurrency can be used to detect whether an entity has been modified since it was last retrieved by using ‘ETag’ and ‘If-Match Header’.
  • Etag:
    • Each time when we retrieve an entity it will include a @odata.etag
  • eTag

    eTag

    • The value of this property is updated each time the entity is updated.
    • Refer this article how to fetch Etag.
  • If-Match Header
    • If-Match header with the ETag value can be used to check whether the current value on the server matches the one found when the user last retrieved the record.

Sample Script:

Key Points to perform Optimistic Concurrency:

  • Get the @odata.etag property of record up on retrieval.
  • ‘Status’ code would be 412, if the current record is different from the server.

function updateRecord() {
var clientURL = Xrm.Page.context.getClientUrl();
var accountId = “f26b5f92-5798-e511-80e3-3863bb2ead80”;
var req = new XMLHttpRequest()
req.open(“PATCH”, encodeURI(clientURL + “/api/data/v8.0/accounts(” + accountId + “)”), true);
req.setRequestHeader(“If-Match”, “W/\”632353\””);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);

req.onreadystatechange = function () {
if (this.readyState == 4) {
req.onreadystatechange = null;
if (this.status == 204) {
var data = JSON.parse(this.response, dateReviver);
}
else if (this.status == 412) {
var error = JSON.parse(this.response).error;
alert(“Precondition Failed – ” + error.message);
}
else {
var error = JSON.parse(this.response).error;
alert(“Error updating Account – ” + error.message);
}
}
};

// Set Account record properties
req.send(JSON.stringify({ name: “Rajeev Pentyala” }));
}

function dateReviver(key, value) {
var a;
if (typeof value === ‘string’) {
a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] – 1, +a[3], +a[4], +a[5], +a[6]));
}
}
return value;
};

Server Response

  • Web API call fails with 412 code, if the Etag value sent with the If-Match header is different from the current value in server.
Optimistic Concurrency

Optimistic Concurrency

  • If the value had matched, a 204 status is expected.

🙂