如何创建 Apex Class?

How to create an Apex Class?

通过大量试验和错误,我在我的沙箱中创建了功能触发器。我的问题是我现在想将它应用到我的现场组织,但我似乎无法理解整个顶点 class 事情。

如何创建 class?

我的触发器背后的想法是,当保存商机记录时,soql 查询将查看在类别字段中选择的选项列表值,并找到具有匹配名称的活动供应商或会员服务帐户类型,并带来通过其销售人员 ID。将该 sfid 放入我的供应商名称查找字段将使我能够在机会和 vendor/member 服务帐户之间建立关系,我需要其他工作流规则和字段更新。

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

在建议您将其部署到实时组织之前,我想指出您的代码的一些问题。

  1. 您正在 for 循环中使用 SOQL 语句。在 SF 环境中,每个事务只能进行 101 个 SOQL 查询。当您对 OPP 进行大量更新时,如果更新数量超过 101 个,您将遇到 SOQL LIMIT:查询太多。 description here

  2. 为了能够部署到生产组织,您需要有测试覆盖率。因此,为了能够将此触发器部署到生产环境中,您需要创建一个测试。 basic resources here。不要忘记进行一些批量测试 运行.

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

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

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

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

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