Разработка
26
Мар
6

Замена отображаемого в Lookup’е текста произвольным значением с помощью плагина

Решение аналогичное Отображение в Lookup’е произвольного поля вместо основного атрибута, но только с использованием плагина (вместо JavaScript’а).

Если в кратце, то берем на какой либо карточке из лукапа GUID, выцепляем с соответствующей ему записи значения необходимого поля (полей) и подставляем его вместо отображаемого значения в лукап. рассмотрим на примере поля Потенциальный клиент формы Возможная сделка:

  • Создайте новый плагин с таким кодом:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Crm.Sdk;
    using Microsoft.Crm.SdkTypeProxy;
    using Microsoft.Crm.Sdk.Query;
    
    namespace LookupTextPlugIn
    {
        public class LookupRetrieveHandler : IPlugin
        {
            DynamicEntity CustomerInfo;
    
            public void Execute(IPluginExecutionContext context)
            {
                // Получаем выходные параметры с retrieve message
                DynamicEntity entity = (DynamicEntity)context.OutputParameters[ParameterName.BusinessEntity];
    
                // Если поле Клиент не заполнено, то прекращаем выполнение...
                if (!entity.Properties.Contains("customerid")) return;
                // ... иначе заносим его в объект с классом Customer
                Customer Customer = (Customer)entity.Properties["customerid"];
    
                // Формируем запрос полей, которые будем отображать в лукапе
                // В зависимости от типа выбранного клиента (Контакт или Бизнес-партнер) запрашиваем различные данные
                ColumnSet customerColumns = new ColumnSet();
                switch (Customer.type)
                {
                    case "account":
                        customerColumns.AddColumn("accountnumber");
                        customerColumns.AddColumn("primarycontactid");
                        customerColumns.AddColumn("telephone1");
                        break;
                    case "contact":
                        customerColumns.AddColumn("salutation");
                        customerColumns.AddColumn("jobtitle");
                        customerColumns.AddColumn("parentcustomerid");
                        break;
                }
    
                // Настраиваем CRM Service через контекст плагина
                ICrmService Service = context.CreateCrmService(true);
    
                // Формируем запрос к CRM Service
                TargetRetrieveDynamic targetRetrieve = new TargetRetrieveDynamic();
                targetRetrieve.EntityId = Customer.Value;
                targetRetrieve.EntityName = Customer.type;
    
                RetrieveRequest retrieveRequest = new RetrieveRequest();
                retrieveRequest.ColumnSet = customerColumns;
                retrieveRequest.ReturnDynamicEntities = true;
                retrieveRequest.Target = targetRetrieve;
    
                // Выполняем запрос данных Клиента
                RetrieveResponse retrieveResponse = (RetrieveResponse)Service.Execute(retrieveRequest);
                
                // Полученные данные заносим в глобальный (для доступа к нему из других функций) динамический объект
                CustomerInfo = (DynamicEntity)retrieveResponse.BusinessEntity;
    
                // Если ничего не возвращено - прекращаем выполнение
                if (CustomerInfo == null) return;
    
                // Формируем строку, которую поместим в лукап
                StringBuilder lookupText = new StringBuilder();
                lookupText.Append(Customer.name).Append(" ");
    
                switch (CustomerInfo.Name)
                {
                    case "account":
                        lookupText.Append(GetProperty("accountnumber")).Append(", ");
                        lookupText.Append(GetProperty("primarycontactid")).Append(", ");
                        lookupText.Append(GetProperty("telephone1"));
                        break;
                    case "contact":
                        lookupText.Append(GetProperty("salutation")).Append(", ");
                        lookupText.Append(GetProperty("jobtitle")).Append(", ");
                        lookupText.Append(GetProperty("primarycustomerid"));
                        break;
                }
    
                // Подменяем отображаемое в лукапе значение
                Customer.name = lookupText.ToString();
            }
    
            private String GetProperty(string propName)
            {
                if (!CustomerInfo.Properties.Contains(propName))
                {
                    return "";
                }
    
                Object property = CustomerInfo.Properties[propName];
    
                if (property is String)
                {
                    return property.ToString();
                }
                else if (property is Customer)
                {
                    return ((Customer)property).name;
                }
                else if (property is Lookup)
                {
                    return ((Lookup)property).name;
                }
    
                // Остальные типы игнорируем
                return String.Empty;
            }
        }
    }
    

    Этот код смотрит поле customerid и если Вы выбрали Бизнес-партнера, то в лукап подставится имя Бизнес-партнера, его номер и первичный контакт. Если же в лукапе будет выбран Контакт, то отобразится приветствие, должность и название компании. Измените перечень полей, которые необходимо отобразить в лукапе на свое умотрение;

  • Зарегистрируйте плагин в CRM на событие Retrieve, объекта Возможная сделка, стадии Post Stage;
  • Откройте любую карточку Возможной сделки, в которой заполнено поле Потенциальный клиент, и обратите внимание на отображаемое в нем значение.



Комментарии (6)
  • Konstantin 26.03.2010

    А есть ли возможность отображать в представлении выбора нескольких объектов для связи многие-ко-многим?

    Прошерстил вроде бы все темы сайта по кастомизации — не нашел.

    Например, в базе множество продуктов. Нужно отобрать заменители для конкретного продукта. Но по названию продукта невозможно понять, что это за продукт. Нужно, к примеру, также на форме выбора отображать название и артикул товара.

    Возможно ли сделать такое?

    Заранее спасибо.

  • slivka_83 26.03.2010

    Извините, но к сожалению не понял вопроса. 🙂 лучше на конкретном примере и более подробно (до полей желательно) 🙂

  • Konstantin 26.03.2010

    Итак, если вкратце, то мне необходимо изменить стандартную страницу добавления сущностей при связи многие-ко-многим.

    К примеру, есть сущность Продукт. Сущность Продукт связана с сущностью Продукт (с самой собой) связью N:N. Связь называется Аналоги.
    У сущности Продукт есть атрибут Тип продукта (автомобили, телефоны и т.д.; к примеру, пиклист)

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

    Далее мне необходимо добавить аналоги для конкретного продукта. Для этого в списке аналогов жмем кнопку Добавить объект Продукт. Открывается форма добавления множества объектов.
    Вот ее то мне и необходимо модифицировать.

    На этой форме по стандарту я вижу только основной атрибут (к примеру, это название продукта). Но по данному атрибуту совершенно невозможно сказать, что это за продукт, и посему крайне сложно отобрать аналоги.

    Если бы мне нужно было только фильтровать однотипные (с одинаковым значением атрибута Тип продукта) записи, то все бы ничего, т.к. можно было бы сделать фильтрованный список. Но в данном случае мне нужно видеть дополнительные атрибуты продуктов в этом гриде, чтобы верно их отобрать в качестве аналогов.

    Стандартно в CRM форма добавления связанных записей N-ой связи (даже 1:N, если вставлять не в поле-лукап) не кастомизируется.
    Возможно были какие-то наработки по этой теме?

    Сразу скажу, что в CRM 2011 этой проблемы уже нет. Такую форму можно настраивать.

    PS: И простите, что так много букв

  • slivka_83 26.03.2010

    Ну, вообщем понятно 🙂 я бы на вашем месте наверно нарисовал плагин, который в возвращаемое название продукта добавлял бы значения какого либо другого поля. По аналогии с http://mmcrm.ru/?p=1090

  • Konstantin 26.03.2010

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

    В принципе это можно назвать workaround’ом: мол добавьте все продукты в список, а затем удалите из него те, которые не проходят по параметрам, но увы вряд ли какой-либо заказчик такое примет %)

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

  • slivka_83 26.03.2010

    Теоретически можно. Ведь чтобы их вытащить и отобразить в далоговом окне лукапа, тоже выполняется какой-то запрос к CRM. А раз так то возвращаемые результат можно (я так думаю) подкорректировать 🙂

*

code