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

Вот сценарий:

  1. Пользователь импортирует потенциальных клиентов с помощью мастера импорта данных.
  2. Если импортируемый интерес уже существует в Salesforce, интерес из электронной таблицы не будет вставлен в Salesforce. И к существующей записи, которая была найдена, должно быть добавлено действие.

У меня есть лид-триггер ниже этого:

  • Добавляет задачу к существующему интересу, но позволяет создать дубликат
  • Или дубликат не удастся вставить, но задача никогда не будет добавлена ​​к существующему интересу.

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

Триггер у меня ниже.

  trigger LeadPreventDuplicate on Lead (after insert,after update) {

Map<String, Lead> leadMap = new Map<String, Lead>();

  for (Lead lead : System.Trigger.new) 
  { 

   if ((lead.Email != null) && (System.Trigger.isInsert ||
        (lead.Email != System.Trigger.oldMap.get(lead.Id).Email))) 
        {
          leadMap.put(lead.Email, lead);
        }
  }

  List<task> addtask=New List<task>();

  for (Lead lead : [SELECT Email FROM Lead WHERE Email IN :leadMap.KeySet()]) 
  {
    Lead newLead = leadMap.get(lead.Email);  // task being added to new Leads but should only be for existing leads
    addtask.add(new Task(
    WhoID =lead.id, 
    Status = 'Active',
    Subject = 'Test Task',
    ActivityDate = system.today()));

   } 
   insert addtask; 

   Lead[] dupes = new Lead[0];
      Set<String> email = new Set<String>(), dupEmail = new Set<String>();
          for(Lead record: Trigger.new)
          email.add(record.email);
          email.remove(null);
          for(Lead record: [SELECT Id, Email FROM Lead WHERE Email IN :email])
                if(!Trigger.newMap.containsKey(record.id))
                dupEmail.add(record.Email);
          for(Lead record: Trigger.new)
    if(dupEmail.contains(record.Email))
        dupes.add(record.clone(true));
    else
        dupEmail.add(record.Email);
delete dupes;
}
0
Mike 20 Янв 2019 в 23:20
3
Привет, Майк, в чем конкретно проблема с кодом, которым ты поделился здесь? Рассматривали ли вы возможность использования собственного управления дубликатами Salesforce вместо кода?
 – 
David Reed
17 Янв 2019 в 19:37
1
Во-вторых, вам следует настоятельно рассмотреть стандартные Управление дубликатами.
 – 
Adrian Larson
17 Янв 2019 в 19:42
Также просто обратите внимание: вы не должны действовать с записями, отличными от trigger.new, в любом контексте before. Вставка новых записей должна происходить в триггере after.
 – 
Adrian Larson
17 Янв 2019 в 19:47
Я просмотрел функциональность управления дублированием, но мне нужно иметь возможность не только предотвратить вставку дубликатов, но и добавить задачу к существующему интересу. Например, существующая запись лида (1) имеет адрес электронной почты test@gmail.com. У пользователя есть csv, в котором есть запись (2), где адрес электронной почты равен test@gmail.com. Импорт должен завершиться неудачно, и запись об активности должна быть добавлена ​​в запись интереса (1). Вы предлагаете мне включить функциональность OTB для управления дубликатами и триггер? Спасибо за ответы.
 – 
Mike
17 Янв 2019 в 19:49
Создано правило сопоставления и дублирования для «Блокировки» при создании и редактировании. Недубликаты лидов вошли, а дубликаты лидов - нет. Это хорошо, за исключением того, что задача никогда не создается для существующих лидов. Попытался использовать мастер импорта данных в Salesforce, используя создание и добавление новых и обновление существующих записей, но действия никогда не отображались для существующих потенциальных клиентов.
 – 
Mike
17 Янв 2019 в 22:12

1 ответ

Лучший ответ

Пользователь импортирует потенциальных клиентов с помощью мастера импорта данных.

Если импортируемый интерес уже существует в Salesforce, интерес из электронной таблицы не будет вставлен в Salesforce. И к существующей записи, которая была найдена, должно быть добавлено действие.

Эти вещи довольно сложно делать вместе. Как вы, вероятно, обнаружили, используя addError()

    newLead.Email.addError('A lead with this email address already exists!');

Действительно блокирует добавление Лида, но это также приводит к откату транзакции, и этот откат уносит с собой вашу новую Задачу. (Я умалчиваю о тонкостях allOrNone=false здесь, потому что вы, как триггер, не можете контролировать, работаете ли вы в контексте allOrNone или нет).

Я думаю, что самый простой способ добиться этого — переместить операцию триггера в after insert, а затем удалить повторяющиеся лиды, а не пытаться заблокировать их от вставки в первую очередь. Хотя есть способ сделать первое, он будет включать в себя передачу идентификаторов «главных» потенциальных клиентов в другую транзакцию через события платформы для вставки задачи (поскольку публикация события платформы не является транзакцией), при использовании addError(), чтобы заблокировать вставку отведений.

Использование метода удаления: вы не можете выполнять DML непосредственно для Trigger.new в контексте after insert (объекты sObject доступны только для чтения), но вы все равно можете удалить их. Это законно, например, если очень странно:

if (Trigger.isAfter && Trigger.isInsert) {
    List<Lead> leads = new List<Lead>();
    for (Lead a : Trigger.new) {
        leads.add(new Lead(Id = a.Id));
    }
    delete leads;
}

Следовательно, если вы переключитесь на использование контекста after insert, вы сможете сохранить добавление задачи и удаление повторяющихся интересов в одном триггере.

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

0
Community 15 Июн 2020 в 11:11
Давид, спасибо за предложение. Я предполагал, что удаление произойдет после вставки задачи. Кроме того, как этот процесс будет чище? Должны ли вставка и удаление задачи быть в отдельных триггерах?
 – 
Mike
18 Янв 2019 в 20:22
Самое чистое решение — использовать готовое управление дубликатами. Я не знаю, откуда берется требование о добавлении задачи, поэтому я не могу это комментировать, но если это подлежит обсуждению, я бы отказался.
 – 
David Reed
18 Янв 2019 в 20:24
Мы регистрируем взаимодействия с клиентами как действия в записи интереса. Запись лида содержит только основную информацию о клиенте, в то время как действия записывают то, что клиент сделал. Я обновил код, который я тестирую, в исходном комментарии. Действия создаются для существующего интереса, но новые интересы не вставляются. Я предполагаю, что это связано с тем, что я изменил триггер после вставки/обновления.
 – 
Mike
18 Янв 2019 в 20:34
Это потому, что ваш триггер удалил все новые лиды, а не только дубликаты.
 – 
David Reed
18 Янв 2019 в 20:36
Хорошо, я вижу это сейчас. Но как мне найти вставленные дубликаты? Мой первоначальный запрос состоит в том, чтобы выбрать адреса электронной почты, которые находятся в объекте Lead, и сравнить их со значениями в наборе ключей. Я не хочу удалять значения, которых нет в наборе ключей, потому что это новые не дублирующиеся лиды. Так нужно ли мне снова запрашивать отдел продаж, чтобы найти только что созданный лид с совпадающим адресом электронной почты?
 – 
Mike
18 Янв 2019 в 23:26