function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Douglas TrasterDouglas Traster 

New Apex Trigger

I am fairly new to Apex.

I broke into 2 triggers, to get it to save .
They are supposed to look at the Opportunity Stage field and then update a custom field on Contacts -- Active_Opportunity__C (a checkbox).  

I am getting 0% code coverage on both and when I enter contact and new opportunity, the contact field is not populating?   What am I doing wrong?

Active_Opportunity__c (Contacts)
False 

Stage (Opportunities)
Closed Won
Closed Lost

Active_Opportunity__c (Contacts)
True

Stage (Opportunities)
Prospecting
Qualified Interest
Needs Analysis
Value Proposition
Proposal/Price Quote
Negotiation/Review
Verbal Commit
Closed Pending

Can I put these 2 into 1 and then would I just mock up an opporunity for the Unit Test?

trigger activeOpportunity on Opportunity (after insert, after update) {
    
    List<contact> conList = new List <contact>();
    
    for (opportunity optyObj: Trigger.new){
        if (optyObj.StageName == 'Closed Won' 
        && optyObj.StageName == 'Closed Lost'
        && optyObj.Contact__c <> null){
            
            conList = [select Id, Active_Opportunity__c from contact where Id = :optyObj.Contact__c ];
            for(contact conObj: conList){
                conObj.Active_Opportunity__c = False;
            }
            update(conList);
        }   
    }
}

trigger activeOpportunity2 on Opportunity (after insert, after update) {
    
    List<contact> conList = new List <contact>();
    
    for (opportunity optyObj: Trigger.new){
        if (optyObj.StageName == 'Prospecting' 
        && optyObj.StageName == 'Qualified Interest'
        && optyObj.StageName == 'Needs Analysis'
        && optyObj.StageName == 'Value Proposition'
        && optyObj.StageName == 'Proposal/Price Quote'
        && optyObj.StageName == 'Negotiation/Review'
        && optyObj.StageName == 'Verbal Commit'
        && optyObj.StageName == 'Closed Pending'
        && optyObj.Contact__c <> null){
            
            conList = [select Id, Active_Opportunity__c from contact where Id = :optyObj.Contact__c ];
            for(contact conObj: conList){
                conObj.Active_Opportunity__c = True;
            }
            update(conList);
        }   
    }
}
 
Best Answer chosen by Douglas Traster
Shruthi Javare GowdaShruthi Javare Gowda
Hi try the below code... it should work as your expectation...

trigger activeOpportunity on Opportunity (after insert, after update) {
    
    List<contact> conUpdList = new List <contact>();
    List<Id> oppConIDList = new List<Id>();
    List<opportunity> oppConList = new List<opportunity>();
    List<Contact> conList = new List<Contact>();
    Map<ID, Contact> conMap = new Map<ID, Contact>();

    
    for (opportunity opp: Trigger.new){
        if(opp.Contact__c!= null){
            oppConList.add(opp);
            oppConIDList.add(opp.Contact__c);
        }
    }   
    
    if(!oppConIDList.isEmpty()){   
        conList  = [select Id, Active_Opportunity__c from contact where Id = :oppConIDList];
    }
        
    if(!conList.isEmpty()){
        for(Contact con : conList){
            conMap.put(con.id,con);     
        }
    }
    
    if(!oppConList.isEmpty()){    
        for(Opportunity optyObj : oppConList){
            Contact c = conMap.get(optyObj.Contact__c);
            if (optyObj.StageName == 'Closed Won' || optyObj.StageName == 'Closed Lost'){
                c.Active_Opportunity__c = False;
            }
            
            else if(optyObj.StageName == 'Prospecting'
            || optyObj.StageName == 'Qualified Interest'
            || optyObj.StageName == 'Needs Analysis'
            || optyObj.StageName == 'Value Proposition'
            || optyObj.StageName == 'Proposal/Price Quote'
            || optyObj.StageName == 'Negotiation/Review'
            || optyObj.StageName == 'Verbal Commit'
            || optyObj.StageName == 'Closed Pending'){
                c.Active_Opportunity__c = True;
            }
            conUpdList.add(c);        
        }
    }
    if(!conUpdList.isEmpty()){
        update conUpdList;
    }
}

Let me know if you any queries...

All Answers

Shruthi Javare GowdaShruthi Javare Gowda
Trigger best practice is to have 1 trigger per object. You can combine both the logics in to a single trigger.
Douglas TrasterDouglas Traster
I know, I am trying to get them together.  Is this how it is done?

trigger activeOpportunity on Opportunity (after insert, after update) {
    
    List<contact> conList = new List <contact>();
    
    for (opportunity optyObj: Trigger.new){
        if (optyObj.StageName == 'Closed Won'
        && optyObj.StageName == 'Closed Lost'
        && optyObj.Contact__c <> null);

        (opportunity optyObj2: Trigger.new)
        if (optyObj.StageName == 'Prospecting'
        && optyObj.StageName == 'Qualified Interest'
        && optyObj.StageName == 'Needs Analysis'
        && optyObj.StageName == 'Value Proposition'
        && optyObj.StageName == 'Proposal/Price Quote'
        && optyObj.StageName == 'Negotiation/Review'
        && optyObj.StageName == 'Verbal Commit'
        && optyObj.StageName == 'Closed Pending'
        && optyObj.Contact__c <> null)
                                        {
            
            conList = [select Id, Active_Opportunity__c from contact where Id = :optyObj.Contact__c ];
            for(contact conObj: conList){
                conObj.Active_Opportunity__c = False;

            conList2 = [select Id, Active_Opportunity__c from contact where Id = :optyObj.Contact__c ];
            for(contact conObj: conList){
                conObj.Active_Opportunity__c = True;
            
            }
            update(conList);
            update(conList2);
        }   
    }
}
Shruthi Javare GowdaShruthi Javare Gowda
what kind of relationship do you have on opportunity and Contact?
Douglas TrasterDouglas Traster
On Opportunity, Contact__c is first and last name. I.e. John Doe.  Contact__c is a lookup to Opportunity.
Shruthi Javare GowdaShruthi Javare Gowda
Hi try the below code... it should work as your expectation...

trigger activeOpportunity on Opportunity (after insert, after update) {
    
    List<contact> conUpdList = new List <contact>();
    List<Id> oppConIDList = new List<Id>();
    List<opportunity> oppConList = new List<opportunity>();
    List<Contact> conList = new List<Contact>();
    Map<ID, Contact> conMap = new Map<ID, Contact>();

    
    for (opportunity opp: Trigger.new){
        if(opp.Contact__c!= null){
            oppConList.add(opp);
            oppConIDList.add(opp.Contact__c);
        }
    }   
    
    if(!oppConIDList.isEmpty()){   
        conList  = [select Id, Active_Opportunity__c from contact where Id = :oppConIDList];
    }
        
    if(!conList.isEmpty()){
        for(Contact con : conList){
            conMap.put(con.id,con);     
        }
    }
    
    if(!oppConList.isEmpty()){    
        for(Opportunity optyObj : oppConList){
            Contact c = conMap.get(optyObj.Contact__c);
            if (optyObj.StageName == 'Closed Won' || optyObj.StageName == 'Closed Lost'){
                c.Active_Opportunity__c = False;
            }
            
            else if(optyObj.StageName == 'Prospecting'
            || optyObj.StageName == 'Qualified Interest'
            || optyObj.StageName == 'Needs Analysis'
            || optyObj.StageName == 'Value Proposition'
            || optyObj.StageName == 'Proposal/Price Quote'
            || optyObj.StageName == 'Negotiation/Review'
            || optyObj.StageName == 'Verbal Commit'
            || optyObj.StageName == 'Closed Pending'){
                c.Active_Opportunity__c = True;
            }
            conUpdList.add(c);        
        }
    }
    if(!conUpdList.isEmpty()){
        update conUpdList;
    }
}

Let me know if you any queries...
This was selected as the best answer
Douglas TrasterDouglas Traster
I am getting the following error : System.NullPointerException: Attempt to de-reference a null object: Trigger.activeOpp: line 42, column 1

Would this be related to the way that Contact__c was set up as First Name last name?  It is not an ID.

I adjusted this piece to get it to run...

if(!oppConIDList.isEmpty()){   
        conList  = [select Name__c, Active_Opportunity__c from contact where Name__c = :oppConIDList];


Do I need to change the first part when selecting the list of things?