Разработка
22
Дек
17

CRM Web Service JavaScript Toolkit

Еще одна реализация фреймворка для упрощенного написания SOAP-запросов (аналог Ascentium CrmService). Функционал:

  • Поддерживает все важные сообщения веб-службы CRM (только синхронный режим):
    • Create
    • Update
    • Delete
    • Fetch
    • Retrieve
    • RetrieveMultiple
    • Execute
  • Инструмент пытается автоматически определить тип данных возвращенных из CRM, при получении сообщения. Единственным исключением является бинарный тип, который нельзя отличить от числового типа (и поэтотому он возвращается в виде числового). Если же Вам необходимо преобразовать его в булевый тип, то воспользуйтесь функцией toBoolean(), которая также входит в этот инструмент.
  • Все поступающие строки запроса/ответа должным образом кодируются или декодируются.

Использование

Как с и Ascentium, чтобы использовать этот инструмент на форме CRM, сначала нужно подключить внешний js-файл (скачайте Web Service JavaScript Toolkit и поместите его в папку ISV в подпапку CrmServiceToolkit, например), в котором и реализована вся логика. Делается это так:

function load_script (url) {
	var x = new ActiveXObject("Msxml2.XMLHTTP");
	x.open('GET', url, false);
	x.send('');
	eval(x.responseText);
	var s = x.responseText.split(/\n/);
	var r = /^(?:function|var)\s*([a-zA-Z_]+)/i;
	for (var i = 0; i < s.length; i++) {
		var m = r.exec(s&#91;i&#93;);
		if (m != null) {
			window&#91;m&#91;1&#93;&#93; = eval(m&#91;1&#93;);
		}
	}
}

load_script("/ISV/CrmServiceToolkit/CrmServiceToolkit.js");
&#91;/javascript&#93;
А теперь несколько примеров по использованию…
<ol>
	<li>Создание записи

// Создаем запись Контакта
var contact = new CrmServiceToolkit.BusinessEntity("contact");
contact.attributes["firstname"] = "Diane";
contact.attributes["lastname"] = "Morgan";
contact.attributes["gendercode"] = 2;
contact.attributes["familystatuscode"] = 1; // Picklist : Single - 1
contact.attributes["creditlimit"] = 3000;
var createResponse = CrmServiceToolkit.Create(contact);
  • Обновление записи
    // Обновляем запись Контакта
    var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C';
    var contact = new CrmServiceToolkit.BusinessEntity("contact");
    contact.attributes["contactid"] = contactId;
    contact.attributes["firstname"] = "Diane";
    contact.attributes["lastname"] = "Lopez";
    contact.attributes["familystatuscode"] = 2; // Married
    var updateResponse = CrmServiceToolkit.Update(contact);
    
  • Получение записи (одной)
    // Возвращаем запись Контакта
    var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C';
    var cols = ["firstname", "lastname", "familystatuscode", "creditlimit", "birthdate", "donotemail"];
    var retrievedContact = CrmServiceToolkit.Retrieve("contact", contactId, cols);alert(retrievedContact.getValue('lastname'));
    alert(retrievedContact.getValue('firstname'));
    alert(retrievedContact.getValue('familystatuscode')); // Пиклист (integer)
    alert(retrievedContact.getValue('familystatuscode', 'name')); // Пиклист (текст)
    alert(retrievedContact.getValue('creditlimit')); // Значение поля Валюта
    alert(retrievedContact.getValue('creditlimit', 'formattedvalue')); // Форматированное значение поля Валюта (string)
    alert(retrievedContact.getValue('birthdate')); // Значение поля Datetime
    alert(retrievedContact.getValue('birthdate', 'date')); // Дата поля Datetime
    alert(retrievedContact.getValue('birthdate', 'time')); // Время поля Datetime
    alert(retrievedContact.getValue('donotemail').toBoolean()); // Битовое поле
    
  • Получение набора записей
    // Возвращаем все записи Контактов, у которых firstname равное John 
    var firstname = 'John'; 
    var query =
    "<q1:EntityName>contact</q1:EntityName>" +
    "<q1:ColumnSet xsi:type='q1:ColumnSet'>" +
       "<q1:Attributes>" +
    		"<q1:Attribute>firstname</q1:Attribute>" +
    		"<q1:Attribute>lastname</q1:Attribute>" +
    		"<q1:Attribute>familystatuscode</q1:Attribute>" +
    		"<q1:Attribute>ownerid</q1:Attribute>" +
    		"<q1:Attribute>creditlimit</q1:Attribute>" +
    		"<q1:Attribute>birthdate</q1:Attribute>" +
    		"<q1:Attribute>donotemail</q1:Attribute>" +
    	"</q1:Attributes>" +
    "</q1:ColumnSet>" +
    "<q1:Distinct>false</q1:Distinct>" +
    "<q1:Criteria>" +
    	"<q1:FilterOperator>And</q1:FilterOperator>" +
    	"<q1:Conditions>" +
    		"<q1:Condition>" +
    			"<q1:AttributeName>firstname</q1:AttributeName>" +
    			"<q1:Operator>Equal</q1:Operator>" +
    			"<q1:Values>" +
    				"<q1:Value xsi:type='xsd:string'>" + firstname + "</q1:Value>" +
    			"</q1:Values>" +
    		"</q1:Condition>" +
    	"</q1:Conditions>" +
    "</q1:Criteria>";
    
    var retrievedContacts = CrmServiceToolkit.RetrieveMultiple(query);
    
    alert(retrievedContacts.length);
    alert(retrievedContacts[0].getValue('lastname'));
    alert(retrievedContacts[0].getValue('firstname'));
    alert(retrievedContacts[0].getValue('familystatuscode');
    alert(retrievedContacts[0].getValue('familystatuscode', 'name'));
    alert(retrievedContacts[0].getValue('creditlimit'));
    alert(retrievedContacts[0].getValue('creditlimit', 'formattedvalue'));
    alert(retrievedContacts[0].getValue('birthdate'));
    alert(retrievedContacts[0].getValue('birthdate', 'date'));
    alert(retrievedContacts[0].getValue('birthdate', 'time'));
    alert(retrievedContacts[0].getValue('donotemail').toBoolean());
    
  • Возвращение набора записей с помощью FetchXML запроса
    // Возвращаем все записи Контактов, у которых firstname равное John, используя FetchXML запрос
    var firstname = 'John';
    var fetchXml =
    "<fetch mapping='logical'>" +
    	"<entity name='contact'>" +
    		"<attribute name='contactid' />" +
    		"<attribute name='firstname' />" +
    		"<attribute name='lastname' />" +
    		"<attribute name='familystatuscode' />" +
    		"<attribute name='ownerid' />" +
    		"<attribute name='creditlimit' />" +
    		"<attribute name='birthdate' />" +
    		"<attribute name='accountrolecode' />" +
    		"<attribute name='donotemail' />" +
    		"<filter>" +
    			"<condition attribute='firstname' operator='eq' value='" + firstname + "' />" +
    		"</filter>" +
    	"</entity>" +
    "</fetch>";
    
    var fetchedContacts = CrmServiceToolkit.Fetch(fetchXml);
    
    alert(fetchedContacts.length);
    alert(fetchedContacts[0].getValue('lastname'));
    alert(fetchedContacts[0].getValue('firstname'));
    alert(fetchedContacts[0].getValue('familystatuscode');
    alert(fetchedContacts[0].getValue('familystatuscode', 'name'));
    alert(fetchedContacts[0].getValue('creditlimit'));
    alert(fetchedContacts[0].getValue('creditlimit', 'formattedvalue'));
    alert(fetchedContacts[0].getValue('birthdate'));
    alert(fetchedContacts[0].getValue('birthdate', 'date'));
    alert(fetchedContacts[0].getValue('birthdate', 'time'));
    alert(fetchedContacts[0].getValue('donotemail').toBoolean());
    
  • Удаление записи
    // Удаляем запись Контакта
    var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C';
    var deleteResponse = CrmServiceToolkit.Delete("contact", contactId);
    alert(deleteResponse);
    
  • Используем сообщение execute чтобы выполнить запрос
    // Используем сообщение execute чтобы выполнить запрос
    var whoAmI = CrmServiceToolkit.Execute("<Request xsi:type='WhoAmIRequest' />");
    currentUserId = whoAmI.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;
    alert("Current user's ID is ' + currentUserId);
    

    CrmServiceToolkit.Execute() может сделать гораздо больше, чем просто WhoAmIRequest. Вообще сообщение Execute является универсальным. Все, чего Вы не можете легко достичь за счет других шести сообщений, Вы можете выполнить используя метод Execute(). Обратитесь к MSCRM 4.0 SDK CRM для более подробной информации по методу Execute MSCRM 4.0 SDK.

  • Примечание

    Инструмент имеет тестовую страничку (CrmServiceToolkitTest.aspx), которая используется для тестирования работоспособности фреймворка. Чтобы ее запустить, разместите ее вместе со всеми другими файлами в папке ISV/CrmServiceToolkit. А затем можете запускать (при условии, что файлы были помещены в папку ISV/CrmServiceToolkit):

    http://crmserver/orgname/ISV/CrmServiceToolkit/CrmServiceToolkitTest.aspx

    Комментарии (17)
    • Костя 22.12.2009

      Какой плагин для WP используешь для подсветки кода?

    • Костя 22.12.2009

      упс, не очень внимательный был, нашел в about SyntaxHighlighter, сорри за оффтоп 🙂

    • Igor 22.12.2009

      У меня Fetch запрос null возвращает. А какие права нужно выдать этому файлу?

    • slivka_83 22.12.2009

      тут не файле дело, а в пользователе который отправляет Fetch запрос. Если у него нет прав на чтение, то он ничего и не получит.

      Или может быть Вы не верно составили Fetch запрос.

    • Igor 22.12.2009

      Права у пользователя есть. Запрос составлен с помощью FetchXML Wizard и данные эта утилита возвращает, а в CRM любое поле со связанного объекта видит как null:
      var z = crmForm.ObjectId;
      var fetchXml = «»+
      «»+
      «»+
      «»+
      «»+
      «»+
      «»+
      «»+
      «»+
      «»;
      var fetchResult = CrmServiceToolkit.Fetch(fetchXml);
      alert(fetchResult.length);
      alert(fetchResult[0].getValue(‘inv_officefromid’));

    • Igor 22.12.2009

      Сори за такое форматирование:)В общем запрос такой:

    • Igor 22.12.2009

      Извиняюсь за флуд, не получается код в камент поставить

      <fetch mapping="logical" count="50" version="1.0">
      	<entity name="inv_kemove">
      		<link-entity name="inv_movementdocument" from="inv_movementdocumentid" to="inv_movementdocumentid">
      			<attribute name="inv_officefromid" />
      		</link-entity>
      	</entity>
      </fetch>
    • slivka_83 22.12.2009

      А обычный Retrieve http://msdn.microsoft.com/en-us/library/cc677076.aspx возвращет данные?

    • Igor 22.12.2009

      Да, такой запрос данные возвращает.

    • Igor 22.12.2009

      Похоже что проблема в сохранении данных, если в связном объекте изменить статус, то данные возвращает.

    • slivka_83 22.12.2009

      Подключил эту библиотеку (версию 2.1) и использовал для запуска бизнес-процессов и fetch-запросов. Никаких проблем вроде не заметил. 🙂

    • Dmitry 22.12.2009

      привет! а как быть с полями типа лукап?
      в асцентиум была функция beContact.attributes[«customerid»] = new CrmLookup(«contact», scontactId);

      здесь подобную не нашел

    • Dmitry 22.12.2009

      нашел ответ в блоге разработчика.
      возможно кто-то еще сталкнется с подобным вопросом
      opportunity.attributes[«customerid»] = { value: contactid, type: «contact» };

    • Mike 22.12.2009

      Не подскажете эта штуковина на CRM-11 будет работать?

    • slivka_83 22.12.2009

      Ну, CRM 2011 поддерживает веб-сервисы CRM 4.0, а значит в теории должно работать 🙂 Но даже если не будет, то я думаю, с той удобной структурой размещения скриптов, которая реализована в CRM 2011, это только вопрос времени (весьяма короткого 🙂 ) когда аналогичные фреймворки появятся и для CRM 2011 🙂

    • Dmitry 22.12.2009

      а у кого-нибудь получилось при помощи этой штуки заполнить поле От и Кому в объекте Звонок.

      выражение
      phonecall1.attributes[«to»] = { value: leadId, type: «lead» }; //кому

      не работает ;(

    • slivka_83 22.12.2009

      молчат… 🙂 наверное никто не пробовал 🙂

    *

    code