I have created a trigger which should create a task on opportunities only when opportunity's owner is active.Here is my trigger and helper class:  Trigger  trigger AutoTaskCreation on Opportunity (before insert, before update, after update) {     if (Trigger.isAfter) {         if (Trigger.isUpdate) {             TaskServices.createTaskforOpp(Trigger.new);         }     }   }  Helper Class  public with sharing class TaskServices {  public static void createTaskforOpp(List&lt;Opportunity&gt; oppList) {      List&lt;Task&gt; taskList = new List&lt;Task&gt;();     For(Opportunity opp : oppList) {       if(opp.Owner.isActive == false) {       Task newTask = new Task(            WhatId = opp.Id,            OwnerId = opp.OwnerId,            ActivityDate = Date.today(),           Subject = 'Test Subject',            Description = 'This a Test'        );         taskList.add(newTask);      }         }         insert taskList;     } }   The above code is creating task for both active and inactive opportunity owners. Why if(opp.Owner.isActive == false) is not working?
51103
I am populating a junction object on from Events and want to capture info from the Event but getting the Account from Account field pulls null. Same who the name via the Who. But if I query the Event record, the AccountId field is populated. And of course, the code compiles properly. Can someone explain how to grab this related info?  trigger TripMeetingFromMeeting on Event (after insert, after update) {      Set&lt;id&gt;EventId = new Set &lt;ID&gt;();     List &lt;Trip_Meeting__c&gt; TMS = new List &lt;trip_meeting__c&gt;();      for (Event E:trigger.new){         if (e.Business_Trip__c!=null){             TMS.add(new Trip_Meeting__c(Meeting__c =e.id, Business_trip__c=e.Business_Trip__c,                                         Meeting_Date__c=e.ActivityDate, Meeting_subject__c=e.Subject,                                        TripNameDELETE__c=e.Business_Trip__r.name,                                         mWhatID__c=e.Whatid,                                        Meeting_Company__c=e.Account.name,                                        Meeting_Name__c=e.Who.name)                                         );          }     }     system.debug('TMS!!!============================'+TMS);      Database.insert(tms, false);  }
32780
To automate some Business process either i can go for  Trigger/ Process Automation which include:- workflow, Approval Process, Process Builder, Visual Workflow.  Both Trigger and Process Automation help me to achieve this. so My Question is:- "when should i use Trigger and when to use Process Automation" ?
40980
The trigger creates a related record when a checkbox is updated. The problem is it is creating a new related record everytime the record is edited. I want to edit the trigger to only create the related record once. (When the criteria is first met). The code is below  Trigger copyEquipmentonsite on Unit_Placements_Sales__c(after insert, after update) {      List&lt;Services__c&gt; sub=new List&lt;Services__c&gt;();      for(Unit_Placements_Sales__c u : Trigger.new) {           if(u.Service_Month_is_Next_Month__c == TRUE) {                 Services__c s = new Services__c();                 s.Equipment_Onsite__c=u.ID;                 s.Equipment_Type__c=u.Equipment__c;                 s.Machine_Specific_Notes__c=u.Machine_Specific_Notes__c;                    s.Product__c=u.The_Product__c;                   s.Dell_Tag_Number__c=u.Dell_Tag_Number__c;                 s.Serial_Number__c=u.Serial_Number__c;                  s.XD_Number__c=u.XD_Number__c;                 sub.add(s);           }           if(sub.size()&gt;0)           insert sub;      } }
56441
I am currently programming a trigger on Opportunities.   I created a test class for this and in my Sandbox I created an account, contact and opportunity. When I try to reference them   Opportunity Opp = [SELECT id from Opportunity where name = 'Test1'];    and then start my   Test.startTest();         Opp.StageName = 'PO in (100%)';          update Opp;         Test.stopTest();   It just errors and shows that Opp returns 0 rows. However when I paste my first bit of code in 'Execute Anonymous' it returns a row and the correct info.   Does this mean I have to create an account, contact, quote and all necessary fields in my test class?
16290
This is a canonical question and answer developed by the community to help address common questions. If you've been directed here, or your question has been closed as a duplicate, please look through the resources here and use them to shape more specific questions. To browse all canonical questions and answers, navigate to the  tag. This question and answer is owned by the community! If you can improve it and make it more useful, you're welcome to edit it. I am building a trigger, a unit test, or other Apex code. I'm working with sObject records, and trying to access related record information. For example, I might have a structure like this: Account a = new Account(Name = 'Test'); insert a;  Opportunity o = new Opportunity(Name = 'Donation', AccountId = a.Id); insert o;  System.assertEquals(o.Account.Name, 'Test', 'Correct Account associated'); // Assertion fails!  Or, in a trigger, I might be aiming for something like this: trigger ContactTrigger on Contact (after insert) {     for (Contact c : Trigger.new) {         if (c.Account.Name == 'Test') {             // Take some action here         }      } }  Why doesn't this work? Why am I getting null values, or NullPointerExceptions?
114740
I have an existing trigger which converts leads into peron accounts if the company name is blank.  Trigger AutoConvert on Lead (after insert) {      LeadStatus convertStatus = [           select MasterLabel           from LeadStatus           where IsConverted = true           limit 1      ];      List&lt;Database.LeadConvert&gt; leadConverts = new List&lt;Database.LeadConvert&gt;();       for (Lead lead: Trigger.new) {           if (!lead.isConverted &amp;&amp; lead.Company == null) {                Database.LeadConvert lc = new Database.LeadConvert();                String oppName = lead.Name;                 lc.setLeadId(lead.Id);                lc.setDoNotCreateOpportunity(true);                lc.setConvertedStatus(convertStatus.MasterLabel);                 leadConverts.add(lc);           }      }       if (!leadConverts.isEmpty()) {           List&lt;Database.LeadConvertResult&gt; lcr = Database.convertLead(leadConverts);      } }   I need to also write a trigger that stops records from coming into Salesforce if that email already exisits in a contact or an account (we use person accounts).  The issue is how do I get it working with the existing trigger (I need it to run before the trigger that converts it into a person account is run).   Is there a way to combine the two or add the functionality to create the record only if the email address doesn't already exist as a contact in the org?
94031
I have a query in a before-update trigger that looks like following:  [SELECT Id,(SELECT Id,Active_opp__c              FROM Opportunities              ORDER BY Days_from_Last_Stage__c ASC)   FROM Account WHERE Id IN: conAccMap.values()]   I have checked this in query plan and it looks like :    Is there a chance that the inner query will cause selective query error since I dont have a WHERE Clause on an indexed field in the inner query?
112048
Background  I'm using  to update some picklist values on the fly. (i.e. Every time a record is inserted/updated/deleted in Table A, I'm adding/subtracting picklist values into a MultiselectePicklist in table B).  Since,     An Apex trigger can execute a callout when the callout is invoked within a method defined as asynchronous: that is, defined with the @future keyword.   I implemented a method with the future annotation, and      For Apex code that is executed asynchronously, such as @future methods, Batch Apex jobs, or scheduled Apex jobs, getSessionId returns null.   so, I needed to pass the session Id as a parameter in the method, I implemented something like:  @future (callout=true) public static void addContactPicklistPreference(List&lt;String&gt; preferences, String sessionId){     Schema.DescribeSObjectResult sObjectDescribe = Contact.sObjectType.getDescribe();     String picklistFieldName = 'Preference__c';                    Picklist_MDT.addPicklistValues(sObjectDescribe, picklistFieldName, artists, sessionId); }  public class Picklist_MDT {      public static void addPicklistValues(Schema.DescribeSObjectResult sObjectDescribe, String picklistFieldName, List&lt;String&gt; picklistValueNames, String sessionId) {         MetadataService.MetadataPort service = createService(sessionId);         ...         }       public static MetadataService.MetadataPort createService(String sessionId) {         MetadataService.MetadataPort service = new MetadataService.MetadataPort();         service.SessionHeader = new MetadataService.SessionHeader_element();         service.SessionHeader.sessionId = sessionId;         return service;     } }   And called the addContactPicklistPreference method from trigger context passing it the UserInfo.getSessionId() value.   Problem  This worked just fine in salesforce classic but not in lightning, when it triggers in lightning I'm getting System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: INVALID_SESSION_ID.... Funny thing is that if I put a System.debug(UserInfo.getSessionId()); before calling the addContactPicklistPreference method it prints a valid session Id in both classic and lightning.  I would really appreciate any input about this.
118936
I am trying to follow the best practice design patterns for triggers but get the error Constructor not defined: [CaseTriggerHandler].(). What am I missing?  Trigger  trigger CaseTrigger on Case (before insert, before update, before delete, after insert, after update, after delete, after undelete) {      CaseTriggerHandler handler = new CaseTriggerHandler();      //Before Insert     if(Trigger.isInsert &amp;&amp; Trigger.isBefore){         handler.OnBeforeInsert(Trigger.new);     }     //After Insert     else if(Trigger.isInsert &amp;&amp; Trigger.isAfter){         handler.OnAfterInsert(Trigger.new);     }     //Before Update     else if(Trigger.isUpdate &amp;&amp; Trigger.isBefore){         handler.OnBeforeUpdate(Trigger.old, Trigger.new, Trigger.newMap);     }     //After Update     else if(Trigger.isUpdate &amp;&amp; Trigger.isAfter){         handler.OnAfterUpdate(Trigger.old, Trigger.new, Trigger.newMap);     }     //Before Delete     else if(Trigger.isDelete &amp;&amp; Trigger.isBefore){         handler.OnBeforeDelete(Trigger.old, Trigger.oldMap);     }     //After Delete     else if(Trigger.isDelete &amp;&amp; Trigger.isAfter){         handler.OnAfterDelete(Trigger.old, Trigger.oldMap);     }     //After Undelete     else if(Trigger.isUnDelete){         handler.OnUndelete(Trigger.new);     } }   Handler      public with sharing class CaseTriggerHandler {      private boolean isExecuting = false;      public CaseTriggerHandler(boolean isExecuting){         this.isExecuting = isExecuting;     }      public void OnBeforeInsert(List&lt;Case&gt; newCases){         //EXECUTE BEFORE INSERT LOGIC     }      public void OnAfterInsert(List&lt;Case&gt; newCases){         //EXECUTE AFTER INSERT LOGIC     }      public void OnBeforeUpdate(List&lt;Case&gt; oldCases, List&lt;Case&gt; updatedCases, Map&lt;Id, Case&gt; CaseMap){         //BEFORE UPDATE LOGIC     }      public void OnAfterUpdate(List&lt;Case&gt; oldCases, List&lt;Case&gt; updatedCases, Map&lt;Id, Case&gt; CaseMap){         //AFTER UPDATE LOGIC     }      public void OnBeforeDelete(List&lt;Case&gt; CasesToDelete, Map&lt;Id, Case&gt; CaseMap){         //BEFORE DELETE LOGIC     }      public void OnAfterDelete(List&lt;Case&gt; deletedCases, Map&lt;Id, Case&gt; CaseMap){         //AFTER DELETE LOGIC     }      public void OnUndelete(List&lt;Case&gt; restoredCases){         //AFTER UNDELETE LOGIC     }      public boolean IsTriggerContext{         get{ return isExecuting;}     } }
86786
I have a problem with my trigger. In Sandbox, everything works fine. When I deploy it to production, I receive multiple exceptions - which is really strange, because I got angry and put the whole code in &quot;try&quot; block. When I put everything in &quot;try&quot; block, it shouldn't be possible not to catch an exception! This is how my code looks: trigger UpdateLeadField on Lead (before insert, before update) {      //debugging in progress     try{         if(Trigger.New[0].SomeField__c==NULL)         {             for(Lead obj: trigger.new)                 obj.SomeField__c = obj.OwnerId;             return;         }              if (Trigger.New[0].OwnerId != Trigger.Old[0].OwnerId)          {             for(Lead obj: trigger.new)             {                 if(Trigger.New[0].SomeField__c==NULL || [SELECT Name FROM UserRole Where Id = :[SELECT Id, UserRoleId FROM User WHERE Id = :obj.OwnerId][0].UserRoleId].Name == 'Some role')                 obj.SomeField__c = obj.OwnerId;             }         }     }     catch (Exception e)     {         System.debug(e);     } }  The main problem seems to be with Web-to-Lead - When deployed, it stops working. The exception:  Apex script unhandled trigger exception by user/organization: 005C00000XXXXXX/00XXXXX0000LXXQ UpdateLeadField: data changed by trigger for field Some field: id value of incorrect type: 00GC00000XXXXXqMAC  &quot;Some field&quot; is a lookup field.
36386
create table employee_tbl ( EmpID int primary key, FirstName varchar(50), LastName varchar(50), Salary float, MobileNo varchar(15) )  create table employeeaudit_tbl ( EmpID int primary key, AuditData varchar(50) )  select * from employee_tbl select * from employeeaudit_tbl  create trigger tr_employee_tbl_forinsert on employee_tbl for insert as begin         declare @EmpID int         select @EmpID = EmpID from inserted          insert into employeeaudit_tbl         values('New employee with EmpID = ' + CAST(@EmpID as nvarchar(5)) +'is added at ' + CAST(GETDATE() as nvarchar(50))) end
51297
I moved a method that sets addError() from a trigger into a Helper class. As I started writing test code for it it seems like the addError() is not actually preventing DML operations for the records that get modified in the helper class.  The information from the SF  states: Marks a trigger record with a custom error message and prevents any DML operation from occurring.  Does this mean that addError() will not work outside of a trigger class?  EDIT  Adding some sample code.  public class MyHelperClass() {     public static void someMethod(Opportunity opp) {         opp.My_Field__c.addError('Some error');         insert opp;     } }   And sample test for it without any asserts:  @IsTest private class MyHelperClass_Test() {     @IsTest     static void someTest() {         Opportunity opp = new Opportunity();         opp.Name = 'Some Name';         opp.StageName = 'Prospect';         opp.CloseDate = Date.today().addDays(30);          MyHelperClass.someMethod(opp);     } }   The above inserts the opportunity and does not trigger an exception. Am I doing something wrong?
91021
trigger AccountReplicate on Account (after delete, after insert, after update) {     if ( trigger.isInsert ) {         for ( Account acc : trigger.new ) {             AccountOne__c ac = new AccountOne__c();             ac.Fax__c = acc.Fax;             ac.Phone__c = acc.Phone;             ac.Name =acc.Name;             insert ac;         }     }      if ( trigger.isUpdate ) {         integer  i = 0;         list&lt;AccountOne__c&gt; a2 = new list&lt;AccountOne__c&gt;([SELECT Id                                                         FROM AccountOne__c                                                         WHERE Name =: trigger.old[i].Name ]);         for ( AccountOne__c c1 : a2 ) {             c1.Name = trigger.new[i].name;             c1.Fax__C = trigger.new[i].Fax;             c1.Phone__C = trigger.new[i].Phone;             i++;         }         update a2;     } }   I tried bulk trigger for the update operation, but it's not working can anyone help me?
89603
Here I'm talking about a handler that covers all the s and that accepts SObjects of arbitrary type. And the recursion problem is where a change caused by a trigger results in that trigger getting called again and so on creating an infinite loop.  So an example trigger would be:  trigger ExampleTrigger on Example__c (before insert, before update, before delete,         after insert, after update, after delete, after undelete) {      SObjectType t = Example__c.SObjectType;     MyHandler.handle(t, Trigger.operationType, Trigger.oldMap, Trigger.newMap); }   with the handler:  public inherited sharing MyHandler {      public void handle(SObjectType t, TriggerOperation op,             Map&lt;Id, SObject&gt; oldMap, Map&lt;Id, SObject&gt; newMap) {          // Logic conditional on t and op that does updates that cause recursion         ...     } }   Often single static Boolean flags are talked about to block trigger recursion. (Though an approach based on change checking that is designed to settle to the correct state can be needed instead to produce the correct business results.)  But for the simple case of complete blocking, (and now I'm writing this I think the answer is "yes"), is this pattern sufficient?  public inherited sharing MyHandler {      // Implements equals and hashCode     private class Kind {         ...     }      private static final Set&lt;Kind&gt; BLOCKED = new Set&lt;Kind&gt;();      public void handle(SObjectType t, TriggerOperation op,             Map&lt;Id, SObject&gt; oldMap, Map&lt;Id, SObject&gt; newMap) {          if (BLOCKED.contains(new Kind(t, op))) return;         ...         BLOCKED.add(new Kind(t, TriggerOperation.BEFORE_INSERT));         BLOCKED.add(new Kind(t, TriggerOperation.AFTER_INSERT));         insert sobs;         ...     } }
17653
Some of code I read in trigger is like this    for(account a: [select id  from account where id in: mapAccount.keySet()]) {     //code      }    some are like   List&lt;Account&gt; listAccount = [select id  from account where id in: mapAccount.keySet()];   for(Account a: listAccount ){   //coode   }   Are those same from performance view?which one is better?
56424
I need help to create a test class for my trigger below: trigger UpdateLeadLastMQLDate on Event (before update) {   Map&lt;Id, Lead&gt; leads = new Map&lt;Id, Lead&gt;();      for(Event record: Trigger.new) {         if(record.WhoId?.getSObjectType() == Lead.sObjectType) {             leads.put(record.WhoId, null);         }     }     leads.putAll([SELECT Last_MQL_Date_Time__c FROM Lead WHERE Id = :leads.keySet()]);     for(Event record: Trigger.new) {         record.Lead_Last_MQL_Date_Time__c= leads.get(record.WhoId)?.Last_MQL_Date_Time__c;     } }  Here the test class: @isTest (seeAllData=false) private class TestUpdateLeadLastMQLDate {     static testMethod void testEventTrigger() {         // set up leads         List&lt;Lead&gt; testLeads = new List&lt;Lead&gt;();         Lead lead1 = new Lead();         lead1.Company = 'Test 1 New Company';         lead1.LastName = 'Brian';         lead1.LeadSource = 'Website';         lead1.Status = 'MQL';         lead1.Email = 'test@test.com';         lead1.Country = 'USA';         lead1.Last_MQL_Date_Time__c = DateTime.parse('17/06/2020 13:00');         //lead1.Business_Type__c = 'App/Business';         //lead1.Lead_Role__c = 'Product';         testLeads.add(lead1);                  Lead lead2 = new Lead();         lead2.Company = 'Test 12';         lead2.LastName = 'Jordan';         lead2.LeadSource = 'Personal';         lead2.Status = 'New';         lead2.Email = 'test23@test.com';         lead2.Country = 'France';         lead2.Last_MQL_Date_Time__c = DateTime.parse('17/06/2020 13:00');         //lead2.Business_Type__c = 'App/Business';         //lead2.Lead_Role__c = 'Product';         testLeads.add(lead2);         insert testLeads;                  // set up Events         List&lt;Event&gt; events = new List&lt;Event&gt;();         Event event1 = new Event();         event1.WhoId=testLeads[0].Id;          event1.Subject= 'Test0';         event1.Type='New';         event1.STARTDATETIME=System.today();         event1.ENDDATETIME=System.today();         event1.Sales_Rep__c = '0052o000009lZyVAAU';         event1.Description = 'bla';         events.add(event1);                           Event event2 = new Event();         event2.WhoId=testLeads[1].Id;          event2.Subject= 'Test1';         event2.Type='Other';         event2.STARTDATETIME=System.today();         event2.ENDDATETIME=System.today();         event2.Sales_Rep__c = '0052o000009lZyVAAU';         event2.Description = 'bla';         events.add(event2);              Test.startTest();         insert events;         Test.stopTest();                  /*List&lt;Lead&gt; leadResults = [SELECT Last_MQL_Date_Time__c FROM Lead WHERE Id IN :testLeads];*/         List&lt;Event&gt; eventResults = [SELECT Lead_Last_MQL_Date_Time__c FROM Event WHERE Id IN :events];         for (Event e : eventResults) {             //System.assertEquals(true, l.SQL_Scheduled__c);             System.assertEquals(e.Lead_Last_MQL_Date_Time__c, DateTime.parse('17/06/2020 13:00'));         }     } }
76405
I want to update the field in multiple records based on the unique_pile_id__c that is unique for all the multiple records. I am trying to write trigger like this:  trigger opMetricsTrigger on Operational_Metrics__c (before insert,before update)  {     Operational_Metrics__c[] op=null;     Set&lt;Id&gt; opIds = new Set&lt;Id&gt;();     public static boolean run = true;      if(run)     {         run=false;         for (Operational_Metrics__c e : Trigger.new)          {             if(e.Unique_Pile_ID__c != null)                 opIds.add(e.Unique_Pile_ID__c );         }          Map&lt;Id, Operational_Metrics__c&gt; y =              new Map&lt;Id, Operational_Metrics__c&gt;([select Unique_Pile_ID__c,unique_id__C,                  Project__c,Composting_Method__c,Pile_Monitoring_Date__c,Average_Temperature__c,                 Moisture_Test__c,Pile_Monitoring_Action_Taken__c,Other_Action__c,                 Pile_Input_Register_Date__c,Total_Waste_Input_on_the_Pile__c,                 Pile_Completion_Stage__c,Date_Pile_COmpleted__c,Curing_Batch_Register_Date__c,                 No_of_Days__c  from operational_metrics__c                  where Unique_Pile_ID__c in :opIds]);          for (Operational_Metrics__c oc : [select Unique_Pile_ID__c,unique_id__C,              Project__c,Composting_Method__c,Pile_Monitoring_Date__c,Average_Temperature__c,             Moisture_Test__c,Pile_Monitoring_Action_Taken__c,Other_Action__c,             Pile_Input_Register_Date__c,Total_Waste_Input_on_the_Pile__c,             Pile_Completion_Stage__c,Date_Pile_COmpleted__c,Curing_Batch_Register_Date__c,             No_of_Days__c  from operational_metrics__c where Unique_Pile_ID__c in :opIds])          {             System.debug('oc '+y.get(oc.Unique_Pile_ID__c));         }       } }   But when I am saving a record it is throwing:      execution of BeforeUpdate caused by: System.StringException: Invalid id: 10-Ber1: External entry point    Here 10-Ber1 is the unique_pile_id__c. Could anyone help me out?