Расширенная функциональность
23
Янв
2

Dynamics 365 или найди 10 отличий… Разработка

Web API

Новая версия

Конечная точка Web API обновилась до версии 8.2 и Вам необходимо использовать следующий URL: /api/data/v8.2/

Metadata Query

Новое улучшение Web API позволяет теперь запрашивать метаданные:

  • Метеданные объекта
    https://xrmtr30.api.crm.dynamics.com/api/data/v8.2/EntityDefinitions(LogicalName='contact')
  • Метаданные объекта вместе со всеми атрибутами
    https://xrmtr30.api.crm.dynamics.com/api/data/v8.2/EntityDefinitions(LogicalName='contact')/Attributes
  • Метаданные одного поля
    https://xrmtr30.api.crm.dynamics.com/api/data/v8.2/EntityDefinitions(LogicalName='contact')/Attributes(LogicalName='firstname')
  • Метаданные глобального Optionsets
    https://xrmtr30.api.crm.dynamics.com/api/data/v8.2/GlobalOptionSetDefinitions(Name='decisionmaker')
  • Метаданные отношений
    https://xrmtr30.api.crm.dynamics.com/api/data/v8.2/RelationshipDefinitions(SchemaName='contactleads_association')

Возвращение объекта после создания/обновления

До D365, когда Вы создавали (или обновляли) запись в CRM, через Web API или через Organization Service, все что Вы получали в ответном сообщении это GUID созданной/обновленной записи. И если бы Вы хотели получить всю запись целиком, Вам потребовалось бы снова ее запрашивать по имеющемуся GUID’у.

В D365 Вы можете передать дополнительный параметр Prefer в заголовке запроса создания, чтобы система вернула Вам созданную запись целиком:

function createAccount() { 
    var serverURL = Xrm.Page.context.getClientUrl(); 
    var account = {}; 
    account["name"] = "Web API representation example"; 
    account["address1_city"] = "Bangalore";
    account["numberofemployees"] = 1000;
    var req = new XMLHttpRequest(); 
    req.open("POST", ServerURL + "/api/data/v8.2/accounts", false); 
    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", "return=representation"); 
   
    req.send(JSON.stringify(account)); 
    
    var response = req.responseText; 
}

З.Ы. В случае возвращения объекта, код успешного статуса будет 201 (вместо 204).

Вы можете указать какие конкретно поля хотите вернуть с помощью опции $select:

  • Создание:
    [Organization URI]/api/data/v8.2/accounts?$select=name,creditonhold,address1_latitude,description,revenue,accountcategorycode,createdon
  • Обновление:
    [Organization URI]/api/data/v8.2/accounts(00000000-0000-0000-0000-000000000001)?$select=name,creditonhold,address1_latitude,description,revenue,accountcategorycode,createdon

Новые действия

В предыдущем выпуске по платформе я рассказывал, что Процессы в D365 обзавелись новыми стандартными действиями. Те же самые действия добавились и для вызова через Web API. Например, QualifyLead:

function qualifyLead(leadId, clientUrl) {
    var functionName = "qualifyLead >>";
    var query = "";
    try {

        // Определяем действие
        query = "leads(" + leadId.replace("}", "").replace("{", "") + ")/Microsoft.Dynamics.CRM.QualifyLead";

        // Задаем параметры запроса
        var data = {
            "CreateAccount": true,
            "CreateContact": true,
            "CreateOpportunity": true,
            "Status": 3
        };

        // Формируем запрос
        var req = new XMLHttpRequest();
        req.open("POST", clientUrl + "/api/data/v8.2/" + query, 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 || this.status == 204) {
                    // success callback
                    var result = JSON.parse(this.response);

                } else {
                    // error callback
                    var error = JSON.parse(this.response).error;
                }
            }
        };
        req.send(JSON.stringify(data));

    } catch (e) {
        throwError(functionName, e);
    }
}

Developer Toolkit

После длительного ожидания и пропущенных версий CRM Microsoft наконец то соизволила обновить Developer Toolkit.

Новая версия поддерживает плагины, БП, генерацию классов, кастомные операции, Веб-ресурсы, генерацию БП, отладку и много другое.

  • Новая версия поддерживает VS версии 2012, 2013, 2015.
  • На локальной машине должен быть установлен CRM SDK версии 8.2 (хотя билдить можно и под более ранние версии).

Скачать расширение для VS можно здесь: https://visualstudiogallery.msdn.microsoft.com/65199277-820a-4315-8783-82da19bd04d8

Первая вещь, которую необходимо сделать после установки – указать путь к инструментам SDK. Для этого перейдите Tools — Options — CRM Developer Toolkit — Tool Paths и укажите путь до Plugin Registration tool и папки bin из SDK. После перезапустите Visual Studio.

Из нововведений можно отметить следующие:

  • Шаблоны для разработки мобильных приложений (но только для устройств на базе Windows).
  • Мастер настройки при создании новых солюшенов для D365.




JavaScript

Мобильные скрипты

Offline

API обзавелся новым пространством имен Xrm.Mobile.offline, благодаря которому Вы можете создавать, возвращать, обновлять и удалять записи в мобильных клиентах D365 находясь офлайн. Работать он будет только в режиме офлайн и только для объектов, для которых включена оффлайновая синхронизация.

Подробнее читаем тут: https://technet.microsoft.com/en-us/library/mt787123.aspx

Utility

Телефоны и планшеты обзавелись новыми клиентскими скриптами, которые используют функционал чисто мобильных устройств:

getCurrentPosition

Возвращает текущую позицию используя геолокационные возможности девайса.

Xrm.Utility.getCurrentPosition().then
(function (location) {
    Xrm.Utility.alertDialog("Latitude: " + location.coords.latitude +
    ", Longitude: " + location.coords.longitude);
},
function (error) {
    Xrm.Utility.alertDialog(error.message);
})

getBarcodeValue

Возвращает информацию штрих коде, такую как номер продукта, отсканированный с использованием камеры устройства.

Xrm.Utility.getBarcodeValue().then(
function (result) {
    Xrm.Utility.alertDialog("Barcode value: " + result);
},
function (error) {
    Xrm.Utility.alertDialog(error.message);
})

Редактируемый грид

Функции

Для работы со строками редактируемых Представлений можно использовать следующие функции:

  • getTotalRecordCount() – возвращает общее количество записей в Представлении с учетом фильтра (во всем Представлении, а не только на текущей странице).
    Примечание: данная функция не учитывает новые или удаленные записи после отрисовки Представления. Воркэраундом может быть принудительный рефреш Представления перед использованием функции.

    Пример:

    var myContactsGridOnloadFunction = function () {
        console.log("Contacts Subgrid OnLoad occurred");
        var count = Xrm.Page.getControl("Contacts").getGrid().getTotalRecordCount();
    };
    
    // После отрисовки контрола вызываем функцию 
    Xrm.Page.getControl("Contacts").addOnLoad(myContactsGridOnloadFunction);
    
  • getRows() – возвращает коллекцю всех выведенных в Представлении записей.
    getRows().getLength() возвратит их количество.

    Пример:

    var rows = Xrm.Page.getControl(opptyProductSubGridName).getGrid().getRows();
    var rowLength = rows.getLength();
    

События

Как работает редактируемое Представления и как к нему цепляются скрипты я описывал ранее. А теперь посмотрим пару реалистичных примеров обработки событий.

OnRecordSelect

Как уже говорилось в описании функционала редактируемых сеток – им пофиг на настройки видимости и чтения полей на уровне формы. И единственный способ избирательно ограничить их редактирование (без использования Безопасности на уровне полей) – скрипт. Щас посмотрим, как это сделать.

Для примера создайте JS Веб-ресурс со следующим кодом:

function onrowselect(executionContext){ 
    var entityObject = executionContext.getFormContext().data.entity; 
    entityObject.attributes.forEach(function (attribute, i) { 
        if (attribute.getName() == "emailaddress1") { 
            var emailControl = attribute.controls.get(0); 
            emailControl.setDisabled(true); 
            break; 
        } 
    });  
}

Прицепите его к гриду и повесьте вызов функции onrowselect на событие OnRecordSelect. Также поставьте галку передачи контекста.

Код берет из контекста текущую выделенную строку, проходится по всем ее полям и блочит их (стандартным методом).

OnChange

В качестве демонстрации события onChange проверим значение поля ContactCode.

Создайте JS Веб-ресурс со следующим кодом:

function EditableGridFieldValidation(executionContext) {
    var gridObject = executionContext.getFormContext().data.entity;
    var contactCodeValue = gridObject.attributes.getByName('new_contactcode').getValue();
    var contactCodeField = gridObject.attributes.getByName('new_contactcode').controls.getByIndex(0);

    if (contactCodeValue.length < 4) {
        contactCodeField.setNotification('Код меньшне 4 символов', 'ValidationAlert');
    }
    else {
        contactCodeField.clearNotification('ValidationAlert');
    }
}

Прикрепите его к сетке и на событие onChange вызовите функцию EditableGridFieldValidation. Также поставьте галочку передающие контекст в функцию.

Здесь мы просто вытаскиваем из переданного контекста значение поля, а также получаем ссылку на само поле. Если проверка значения не удовлетворяет требования – выводим сообщение рядом с полем.

Discovery Service

С запуском D365 появилась и глобальная служба Discovery Service (для онлайн). Ранее чтобы получить организации Пользователя, необходимо было обратится к Discovery Service кокретного региона. Работает она только для Web API.

Глбальный URL выглядит так:

https://globaldisco.crm.dynamics.com/api/discovery/v1.0/Instances

вместо конкретного региона:

https://disco.crm3.dynamics.com/api/discovery/v8.0/Instances

Более подробно читайте в: https://msdn.microsoft.com/en-us/library/mt607485.aspx

Server-to-server authentication

CRM (онлайн) обзавелся возможностью аутентификации Server-to-server. Это когда сторонее приложение (размещенное в Azure) получает доступ к CRM без всяких пользовательских логинов и паролей. Для этого конечно же нужна предварительная настройка и выдача прав для такого приложения. Более подробно читайте тут:

З.Ы. Для настройки такой аутентификации у карточки Пользователя в CRM появилась отдельная форма – Пользователь прилоежния.

Комментарии (2)
  • genesario 23.01.2017

    В Editable Grid Возможна реализация зависмых пиклистов?

  • slivka_83 23.01.2017

    Не уверен, надо пробовать…

*

code