2013-03-05 3 views
2

Я пытаюсь сделать деятельность, которая переносит адрес от ведущего к контакту. Мы не используем по умолчанию Address1 и Address2 в нашем развертывании CRM (не мое решение), поэтому, хотя процесс Qualification копирует адрес, введенный в начало контакта, он делает это, используя поля Address1. Я использую код ниже, и все, кажется, работает (нет ошибок регистрации, нет ошибок, выполняющих рабочий процесс, который использует это действие). Есть только одна проблема ... ничего не происходит. Хотя ошибок нет, адрес не создается. Я работаю как администратор CRM, поэтому это не должно быть правкой, но даже если это не должно генерировать исключение безопасности? Любые идеи, почему это не работает?CRM create CustomerAddress Programmatically

public class MigrateLeadAddressToContactActivity : CodeActivity 
{ 
    [Input("Contact input")] 
    [ReferenceTarget("contact")] 
    public InArgument<EntityReference> InContact { get; set; } 

    protected override void Execute(CodeActivityContext executionContext) 
    { 
     // Get the tracing service                         
     var tracingService = executionContext.GetExtension<ITracingService>(); 

     if (InContact == null) 
     { 
      const string errorMessage = "Contact was not set for Address Migration Activity"; 
      tracingService.Trace(errorMessage); 
      throw new InvalidOperationException(errorMessage); 
     } 

     // Get the context service.                         
     var context = executionContext.GetExtension<IWorkflowContext>(); 
     var serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); 

     // Use the context service to create an instance of CrmService.             
     var service = serviceFactory.CreateOrganizationService(context.UserId); 

     //Retrieve the contact id 
     var contactId = this.InContact.Get(executionContext).Id; 

     // Get The Lead if it exists 
     var query = new QueryByAttribute 
        { 
         ColumnSet = new ColumnSet(
          new[] 
          { 
           "address1_line1", 
           "address1_line2", 
           "address1_line3", 
           "address1_city", 
           "address1_stateorprovince", 
           "address1_postalcode", 
           "address1_country", 
          } 
         ), 
         EntityName = "lead" 
        }; 

     // The query will retrieve all leads whose associated contact has the desired ContactId 
     query.AddAttributeValue("customerid", contactId); 

     // Execute the retrieval. 
     var results = service.RetrieveMultiple(query); 

     var theLead = results.Entities.FirstOrDefault(); 
     if (null == theLead) 
     { 
      tracingService.Trace("Activity exiting... Contact not sourced from Lead."); 
      return; 
     } 

     var newAddress = new Entity("customeraddress"); 
     newAddress.Attributes["name"] = "business"; 
     newAddress.Attributes["objecttypecode"] = "contact"; 
     newAddress.Attributes["addresstypecode"] = 200000; 
     newAddress.Attributes["parentid"] = new CrmEntityReference("contact", contactId); 
     newAddress.Attributes["line1"] = theLead.Attributes["address1_line1"]; 
     newAddress.Attributes["line2"] = theLead.Attributes["address1_line2"]; 
     newAddress.Attributes["line3"] = theLead.Attributes["address1_line3"]; 
     newAddress.Attributes["city"] = theLead.Attributes["address1_city"]; 
     newAddress.Attributes["stateorprovince"] = theLead.Attributes["address1_stateorprovince"]; 
     newAddress.Attributes["postalcode"] = theLead.Attributes["address1_postalcode"]; 
     newAddress.Attributes["country"] = theLead.Attributes["address1_country"]; 

     service.Create(newAddress); 
     tracingService.Trace("Address Migrated from Contact to Lead."); 
    } 
+0

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

ответ

0

Если предположить, что действительно нет исключений, брошенных, единственный выход для этой части коды здесь

if (null == theLead) 
{ 
    tracingService.Trace("Activity exiting... Contact not sourced from Lead."); 
    return; 
} 

Так было бы справедливо предположить, что theLead равна нуль в этой точке и рабочий процесс завершается корректно.

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

+0

Похоже, что процесс квалификации не устанавливает customerId на Lead, который согласно документации: «Уникальный идентификатор учетной записи или контакт, связанный с ведущим». CRM снова наносит урон ... думаю, мне придется как-то обойти это. Спасибо вам за помощь glosrob (и Daryl). – Bitfiddler

0

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

0

Попробуйте найти возвращаемый GUID из Service.Create и посмотреть, что содержит.

Что-то вроде:

Guid addressId = service.Create(newAddress); 
tracingService.Trace(string.format("Address ID Result: {0}", addressId)); 
+0

Вопрос: Где я могу найти выход из трассы? Я не нашел на этом хорошего ответа. Я пробовал несколько вещей, но не смог найти, где заканчиваются эти сообщения трассировки. – Bitfiddler

+0

Трассировка указана в сообщении об исключении. Это очень полезно, но также не совсем интуитивно понятно :) Выбросьте исключение по назначению и посмотрите на возвращаемое сообщение об ошибке. Посмотрите на свой след. – glosrob

+0

Я вижу. Спасибо за объяснение. Я никогда бы не догадался, что «Trace» в MS говорит «Дополнительная информация об исключении». Какой странный CRM в мире формируется. Интересно, что даже книги, написанные специально для CRM 2011, опубликованные Microsoft press, не говорят об этом ... grrr. – Bitfiddler

0

Вы, кажется, пытается создать адресную запись напрямую, минуя два уже созданную для контактной записи по умолчанию (он всегда создает эти две записи, используют ли вы их и хотите ли вы, чтобы «тени» из них были видны в форме «Контакт»). Вы говорите, что ничего не происходит - это подтверждается просмотром таблиц SQL или ссылкой «Дополнительные адреса» в записи «Контакт»?

Одна вещь, которую вы, кажется, не указали в создании, указала номер адреса (и в идеале сделайте это, сначала найдя наибольшее число по всем адресам, уже связанным с контактом и увеличивающимся на 1). Это должно быть не менее 3 во всех случаях.

Если вы посмотрите на определение связанного представления объекта, вы увидите, что он явно фильтрует, чтобы включать адреса, где номер адреса> 2, чтобы обеспечить иллюзию, что 1 и 2 являются «частью» контакта и «больше» "являются отдельными записями, тогда как на самом деле все адреса, включая 1 и 2, являются строками в таблице сущностей адреса сами по себе.

Поэтому я подозреваю, что если значение оставлено равным нулю, адрес просто не будет отображаться в графическом интерфейсе, так как он не соответствует критериям фильтра. Он может или не может также не создаваться, поскольку он полагается на это поле довольно интенсивно внутри, поэтому я буду рассматривать его как «требуемую систему» ​​и обязательно включите его в коллекцию столбцов.

Альтернативный подход:

Если вы никогда не используя поля для Add_1 или Add_2 на форме, можно по-прежнему использовать адресную запись с адресом № 2 для хранения данных из свинца, что делает его обновление существующей (пустой) записи, а не создание.

Изменить адрес, связанный вид, чтобы изменить фильтр таким образом, он будет включать в себя Add_2 в представлении, делая это фильтр для номера адреса> 1 вместо 2.

Это будет показываться пользователям, как есть один адрес там уже, и они могут добавить больше с нормальной функциональностью для address_3, 4 и т. д. (которые они могут считать 2, 3 и т. д.). Адрес 1 существует, но пуст и его можно игнорировать.

+0

Привет, Адам, спасибо за ответ. К вашему первому вопросу, да, я подтвердил, что записи фактически не создаются в базе данных. – Bitfiddler

+0

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

+0

Что касается альтернативного подхода, я не могу этого сделать, потому что существующая система имеет кучу рабочих процессов и плагинов, которые принимают адрес 1 и 2, игнорируются. Мне не поручено переписывать существующую/рабочую функциональность, поэтому мне нужно обойти это. – Bitfiddler

0

Ах! Теперь я вижу, что вы делаете запрос назад! (или, скорее всего, вам не нужен запрос)

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

Если вы квалифицируете ведущего и создаете контакт (и/или учетную запись и/или возможность), то поле, которое соединяет их вместе, находится во вновь созданной записи и называется «originatingleadid» во всех трех случаях для всех трех объектов. Обратите внимание, что это поддерживает квалификацию, безоговорочную и переквалификацию руководства несколько раз, и каждая запись, созданная при этом, знает, откуда она взялась (подумайте «кто твой папа?», И вы этого не забудете!).

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

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

Мой другой ответ по-прежнему является лучшим способом справиться с этим процессом в целом, используя обновление, а не создание, но этот ответ должен помочь вам в правильном использовании правильной записи.

0

Если этот код написан для CRM 2011 (и, похоже, что это), то вам необходимо установить значение addresstypecode не с целым числом, но с OptionSetValue объекта:

newAddress.Attributes["addresstypecode"] = 200000; 

становится

newAddress.Attributes["addresstypecode"] = new OptionSetValue(200000); 

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