0
votes

I need to transfer the below trigger logic to an apex class. But in apex class I cant use Trigger.New as it will give error. Once I give the logic in apex call, I can call the method in trigger so, Can anybody please tell me that how can I convert this trigger to an apex class?

trigger updatecontactrolecount on Opportunity(before insert, before update) {
     Boolean isPrimary;
     Integer iCount;
     Map < String, Opportunity > oppty_con = new Map < String, Opportunity > (); //check if the contact role is needed and add it to the oppty_con map
     for (Integer i = 0; i < Trigger.new.size(); i++) {
         oppty_con.put(Trigger.new[i].id,
             Trigger.new[i]);
     }
     isPrimary = False;
     for (List < OpportunityContactRole > oppcntctrle: [select OpportunityId from OpportunityContactRole where(OpportunityContactRole.IsPrimary = True and OpportunityContactRole.OpportunityId in : oppty_con.keySet())]) {
         if (oppcntctrle.Size() > 0) {
             isPrimary = True;
         }
     }
     iCount = 0;
     for (List < OpportunityContactRole > oppcntctrle2: [select OpportunityId from OpportunityContactRole where(OpportunityContactRole.OpportunityId in : oppty_con.keySet())]) //Query for Contact Roles
     {
         if (oppcntctrle2.Size() > 0) {
             iCount = oppcntctrle2.Size();
         }
     }
     for (Opportunity Oppty: system.trigger.new) //Check if  roles exist in the map or contact role isn't required 
     {
         Oppty.Number_of_Contacts_Roles_Assigned__c = iCount;
         Oppty.Primary_Contact_Assigned__c = isPrimary;
     }
 }
1
It's very simple, all you do is pass a map into your class - EricSSH
You can create a static method in a class and pass the Trigger.new map to the class. You can do the same with the Trigger.isInsert and the Trigger.isBefore context variables but you can also check triggered DML type in the trigger and then call appropriate static method from the handler class. One more tip. You can use the Trigger.newMap context variable instead of iterating through the entire trigger context and creating your own map. Google for 'Trigger Context Variables' in APEX for more information. - Paweł Hajduk
It is also a good practice to create only one trigger for a single SObject type and in this trigger only to call proper methods from the handler classes. This way you get more control over the trigger execution order and you can check additional conditions. - Paweł Hajduk

1 Answers

1
votes

You can use a TriggerHandler Class to manage your all your triggerred events in the same place: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigger_Best_Practices

In your trigger call your unique class :

trigger OpportunityTrigger on Opportunity (before insert,after insert,before update,after update, before delete,after delete) {
    try {
        new OpportunityTriggerHandler().run();
    }
    catch(Exception e) {
        System.debug(e);
    }

Then do all the logic in the TriggerHandler :

public with sharing class OpportunityTriggerHandler extends TriggerHandler {
    private Map<Id, Opportunity> newOpportunityMap;
    private Map<Id, Opportunity> oldOpportunityMap;
    private List<Opportunity> newOpportunity;
    private List<Opportunity> oldOpportunity;

    public OpportunityTriggerHandler() {
        this.newOpportunityMap = (Map<Id, Opportunity>) Trigger.newMap;
        this.oldOpportunityMap = (Map<Id, Opportunity>) Trigger.oldMap;
        this.newOpportunity = (List<Opportunity>) Trigger.new;
        this.oldOpportunity = (List<Opportunity>) Trigger.old;
    }

    public override void beforeInsert() {
       for (Opportunity o : this.newOpportunity) {
            if (o.Name == '...') {
                //do your stuff
            }
        }
    }

    public override void afterInsert() {
        //...
    }

}