Разработка
08
Авг
5

Открытие формы в зависимости от значения поля

Формы объектов CRM используются для разграничения логики между различными Ролями Пользователями. Но зачастую они используются не по прямому назначению, а, например, переключатся в зависимости от значения пиклиста. Обычно реализуется это с помощью JS, что имеет один существенный недостаток – при открытии записи формы, в зависимости от значения какого-либо поля, происходит переключение формы, что вызывает ее повторную загрузку.

Это не очень хороши ни с эстетической точки зрения ни с т.з. производительности. Поэтому попробуем подключить что-нибудь посерьёзнее JS и желательно неподдерживаемое 🙂 чтобы избежать двойной загрузки формы. Решение основывается на свойствах пользователя, в которых хранится последняя открываемая форма и которая будет открыта по умолчанию при следующем посещении записи.

Начнем:

  • Создайте пиклист, заполните необходимыми значениями, вынесите на форму и сделайте обязательным для заполнения;
  • Создайте новые формы, чтобы их количество соответствовало значениям пиклиста. Скопируйте значения GUID’ов форм – она нам понадобятся далее;
  • Создайте плагин со следующим кодом:
    using System;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    
    namespace switchforms
    {
        public class switchforms : IPlugin
        {
            public void Execute(IServiceProvider serviceProvider)
            {
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                if (context.Stage == 20) // Стадия Пре
                {
                    // Помещяем значение пиклиста в контекст
                    var columns = (ColumnSet)context.InputParameters["ColumnSet"];
                    if (!columns.Columns.Contains("businesstypecode"))
                        columns.AddColumn("businesstypecode");
                }
                else if (context.Stage == 40) // Стадия Пост
                {
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
    
                    // Возвращаем значение пиклиста из контекста
                    Entity target = (Entity)context.OutputParameters["BusinessEntity"];
                    OptionSetValue businesstypecode = (OptionSetValue)target["businesstypecode"];
    
                    // Определяем необходиму форму по значению пиклиста
                    string formID = "8448B78F-8F42-454E-8E2A-F8196B0419AF"; // Дефолтная форма
                    switch (businesstypecode.Value)
                    {
                        case 1:
                            formID = "8448B78F-8F42-454E-8E2A-F8196B0419AF";
                            break;
                        case 100000001:
                            formID = "A49B4F3B-9851-4710-830E-C72FA7A6703F";
                            break;
                        case 100000002:
                            formID = "E6EAAFA2-19D0-4AD4-B42E-344F6480F445";
                            break;
                    }
    
                    // Возвращаем настройки интерфейса текущего пользователя для определенного объекта
                    QueryExpression query = new QueryExpression("userentityuisettings");
                    query.Criteria.AddCondition("ownerid", ConditionOperator.Equal, context.UserId.ToString());
                    query.Criteria.AddCondition("objecttypecode", ConditionOperator.Equal, 1); // Организация
                    EntityCollection UISettingsCollection = service.RetrieveMultiple(query);
    
                    if (UISettingsCollection.Entities.Count > 0)
                    {
                        // Обновляем GUID последней просмотренной формы
                        Entity settings = UISettingsCollection[0] as Entity;
                        settings["lastviewedformxml"] = "<MRUForm><Form Type=\"Main\" Id=\"" + formID + "\" /></MRUForm>"; ;
                        service.Update(settings);
                    }
                }
            }
        }
    }
    

    Как можете заметить процесс двухступенчатый:

    • На стадии Пре мы добавили наш пиклист в набор входящих параметров ColumnSet, чтобы он был доступен на стадии Пост (и не нужно было делать дополнительный запрос для его возвращения);
    • На стадии Пост мы определяем необходимую форму в зависимости от значения пиклиста, а затем обновляем настройки текущего пользователя, указывая последнюю просмотренную форму для нужного объекта;

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

  • Зарегистрируйте плагин в CRM на Retrieve на нужный объект (в данном случае это Организация) на обе стадии (Пре и Пост) в режиме синхронно.

Готово.



Комментарии (5)
  • Michael Goriachev 08.08.2015

    А на какое его событие записывать? Retrieve?

  • slivka_83 08.08.2015

    Да, на Retrieve. Дополнил текст.

  • webmaster 08.08.2015

    Данная фича не работает для кастомных сущностей

  • amarkts 08.08.2015

    Добрый день! Реализовал приведенный вами пример плагина. У меня в CRM 2015 для кастомной сущности при смене значения пиклиста не происходит автоматической смены формы. Форма меняется только в случае ручного обновления страницы. У вас наблюдается подобное поведение или смена формы происходит автоматически при смене значения пиклиста и последующем сохранении?

  • slivka_83 08.08.2015

    Здравствуйте.
    Когда писал пример — наблюдалось 🙂 Сейчас уже не скажу — CRM 2015 у меня уже нету.

*

code