Как создать класс Apex?

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

Как я могу создать класс?

Идея, лежащая в основе моего триггера, заключается в том, что при сохранении записи возможности запрос soql будет смотреть на значение раскрывающегося списка, выбранное в поле категории, и находить активный тип учетной записи поставщика или службы поддержки с совпадающим именем и передавать его идентификатор Salesforce. Добавление этого sfid в поле поиска имени поставщика позволит мне установить связь между возможностью и учетной записью службы поставщика / участника, которая мне нужна для других правил рабочего процесса и обновлений полей.

    trigger Find_Vendor on Opportunity (before insert)
    {
       for(Opportunity u:trigger.new)
       {
          if(u.Vendor_Name__c == null)
          {
              u.Vendor_Name__c =   [Select Id From Account
                             Where (Account_Type__c = 'Vendor'
                             OR Account_Type__c = 'Member Services')
                             AND Status__c = 'Active'
                             AND Name = :u.Category__c limit 1].Id;
          }
       }
    }

person Gabe Mejia    schedule 30.04.2018    source источник
comment
Так ваш триггер работает так, как ожидалось? Правильно ли я понимаю, что вы хотите перенести это сейчас из своей тестовой организации в свою живую?   -  person utm    schedule 30.04.2018
comment
@utm Верно. Просто пытаюсь перенести это из тестовой организации в живую.   -  person Gabe Mejia    schedule 30.04.2018
comment
Дело в том, что вы не можете развернуть что-либо в Live-Org напрямую. Вы должны использовать наборы изменений. Для этого ваша тестовая организация должна быть связана с вашей живой организацией. Если это будет сделано, вы можете создать исходящие ревизии со всеми вашими изменениями (классами и т. Д.) В вашей тестовой организации. Затем этот набор изменений должен быть загружен, и в другой организации (действующей организации) вы можете импортировать этот набор изменений (входящий набор изменений). Я бы рекомендовал прочитать / выполнить руководство Trailhead «Развертывание из песочницы с наборами изменений».   -  person utm    schedule 30.04.2018


Ответы (2)


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

 trigger Find_Vendor on Opportunity (before insert)
{
   Set<String> categories = new Set<String>();
   Map<String, Id> categoryAccountIdMap = new Map<String, Id>();
   for(Opportunity u:trigger.new)
   {
      if(u.Category__c != null)
      {
           categories.add(u.Category__c);
      }
   }
   List<Account> categoryAccounts = [Select Id From Account
                         Where (Account_Type__c = 'Vendor'
                         OR Account_Type__c = 'Member Services')
                         AND Status__c = 'Active'
                         AND Name IN :categories];
   for(Account acct : categoryAccounts){
       if(!categoryAccountIdMap.containsKey(acct.Name)){
            categoryAccountIdMap.put(acct.name, acct.Id);
       }
   }
   for(Opportunity u:trigger.new)
   {
      if(u.Vendor_Name__c == null && categoryAccountIdMap.containsKey(u.Category__c))
      {
          u.Vendor_Name__c =   categoryAccountIdMap.get(u.Category__c);
      }
   }
}

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

@IsTest
private class SomeTestClassName {

@isTest
static void testOppVendor() {
 //you may need to add required fields to these objects to actually insert  them
    Account a = new Account(Name = 'Category 1');
    insert  a;
    Opportunity o = new Opportunity(Name = 'test', StageName = 'Closed Won', Category__c = 'Category 1');
    insert o;
    o = [SELECT Vendor_Name__c FROM Opportunity where Id = :o.Id];
    System.assertEquals(a.Id, o.Vendor_Name__c);
}

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

person Gareth Jordan    schedule 30.04.2018

Я хотел бы указать на некоторые проблемы с вашим кодом, прежде чем даже предлагать вам развернуть его в live org.

  1. Вы используете оператор SOQL для цикла. В среде SF вы ограничены 101 запросом SOQL на транзакцию. Когда вы сделаете массовое обновление своих OPP, а их будет более 101, вы столкнетесь с SOQL LIMIT: слишком много запросов. здесь

  2. чтобы иметь возможность развертывать в производственной организации, вам необходимо иметь тестовое покрытие. Итак, чтобы вы могли развернуть этот триггер в производственной среде, вам необходимо создать тест. здесь. Не забудьте запустить несколько массовых тестов.

  3. Я бы рекомендовал вам не использовать триггеры для фактического выполнения функций. у вас будет огромное количество триггеров в вашей организации, и вам будет сложно управлять порядком их выполнения. попробуйте принять модель, в которой триггер не содержит никакой логики, кроме того, находится ли он до или после обновления и так далее. Основное объяснение можно найти здесь

Отличный ресурс для получения дополнительной информации об ограничениях и передовых методах SF - это sfdc99.com.

person Svatopluk Sejkora    schedule 30.04.2018