0

通过大量的试验和错误,我在我的沙箱中创建了功能触发器。我的问题是我现在想将它应用到我的实时组织中,但我似乎无法理解整个 apex 类的东西。

如何创建课程?

我的触发器背后的想法是,当保存机会记录时,soql 查询将查看在类别字段中选择的选项列表值,并找到具有匹配名称的活动供应商或成员服务帐户类型,并提供其销售人员 ID。将该 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;
          }
       }
    }
4

2 回答 2

0

我不会将此触发器部署到生产中,它有很多问题并且可能会中断,因为您在 for 循环中执行 SOQL 查询,而且逻辑似乎没有经过深思熟虑。看到您似乎不太擅长编写触发器,您可能应该查看一个声明性解决方案,例如流程构建器无头流程,您可以在其中获得相同的结果。如果您坚持使用触发器,我建议您使用以下内容:

 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);
}

话虽如此,这里没有使用许多最佳实践,例如测试数据工厂和将业务逻辑从触发器移动到您绝对应该熟悉的领域类。

于 2018-04-30T16:51:26.023 回答
0

在建议您将其部署到 live org 之前,我想指出您的代码存在的一些问题。

  1. 您正在 for 循环中使用 SOQL 语句。在 SF 环境中,每个事务限制为 101 个 SOQL 查询。当您对您的 OPP 进行大规模更新并且其中超过 101 个时,您将遇到 SOQL LIMIT:太多查询。描述在这里

  2. 为了能够部署到生产组织,您需要有测试覆盖率。因此,为了能够将此触发器部署到生产环境,您需要创建一个测试。基本资源在这里。不要忘记运行一些批量测试。

  3. 我建议您不要使用触发器来实际执行功能。您最终将在您的组织中获得大量触发器,并且您将很难管理它们何时执行的顺序。尝试采用触发器不包含任何逻辑的模型,除非它是在更新之前或之后等等。基本解释可以在这里找到

sfdc99.com是了解更多关于 SF 限制和最佳实践的重要资源。

于 2018-04-30T09:25:50.440 回答