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
Sandra OSandra O 

Combine 2 Opportunity Triggers

Hello,

I'd appreciate help in combining these 2 triggers - I need to keep the functionality of both intact.  Thank you in advance!!

1st one:
trigger linkGoLiveDate on Opportunity (after insert, after update) {

    Set<ID> myAccountIds = new Set<ID>();
    Map<ID, Date> myMap = new Map<ID, Date>();
    
    for (Opportunity o : Trigger.new) {
        if (o.go_live_date__c != null && o.accountid != null) {
            myAccountIds.add(o.accountid);
            myMap.put(o.accountid, o.go_live_date__c);
        }   
    }
    
    if (myAccountIds.size() > 0) {
        List<Account> myAccounts = new List<Account>();
        for (Account a : [select id from account where Service_Start_Date__c = NULL AND id in :myAccountIds]) {
            a.service_start_date__c = myMap.get(a.id);
            myAccounts.add(a);
        }
        
     update myAccounts;
    }

}

2nd one:
trigger updateAccountOwner on opportunity (after insert, after update){
    list<Id> accIds = new list<Id>();
    list<Account> accounts = new list<account>();
    for(opportunity o:trigger.new){
        accIds.add(o.accountId);
    }
    for(account a:[select Id, ownerid from account where Id IN :accIds]){
        for(opportunity opp:trigger.new){
            if(opp.StageName == 'Live'){
                a.ownerid=opp.client_service_rep__c;
                accounts.add(a);
            }
        }
    }
    update accounts;
}

 
Best Answer chosen by Sandra O
robdobbyrobdobby
Hi Sandra,

You can give this a try:
 
// new trigger
// its a best practice to have a single trigger named after the sobject
// since we cannot guarantee order of execution with multiple triggers
trigger Opportunity on Opportunity (after insert, after update) {

    Map<ID, Date> myMap = new Map<ID, Date>();

    // get all the related accounts
    //
	// create a map from account id to the related opportunity
	//
    Map <Id, Opportunity> mapOpps = new Map <Id, Opportunity> ();

    for (Opportunity o : Trigger.new) {
    	mapOpps.put(o.accountId, o);
    }
    
    Map <Id, Account> mapAccounts = new Map <Id, Account> ([select Id, Service_Start_Date__c from Account where Id in :mapOpps.keySet() ]);

    List<Account> updateAccounts = new List<Account>();
    
	// set the account.service_start_date to the related opportunity.go_live_date
	// if the account.service_start_date is null
	// 
	// set the account owner to the opp.client_service_rep
	// if the opp.StageName is 'Live'
	//
    for (Account a : mapAccounts.values()) {
		Opportunity theOpp = mapOpps.get(a.Id);
		if (theOpp != null && ((a.Service_Start_Date__c == null && theOpp.go_live_date__c != null) || theOpp.StageName == 'Live')) {
			Account theAccount = new Account(Id=a.Id);
			
			if (a.Service_Start_Date__c == null && theOpp.go_live_date__c != null) {
				theAccount.service_start_date__c = theOpp.go_live_date__c;
			}
			if (theOpp.StageName == 'Live') {
				theAccount.ownerid = theOpp.client_service_rep__c;
			}
			
			updateAccounts.add(theAccount);
		}
    	
    }

    if (updateAccounts.size() > 0)  {
	    update updateAccounts;
	}
}

I think this is right, but I didn't compile it.  Let me know how it goes.  Good luck!

Rob Kemper - OpFocus

All Answers

robdobbyrobdobby
Hi Sandra,

You can give this a try:
 
// new trigger
// its a best practice to have a single trigger named after the sobject
// since we cannot guarantee order of execution with multiple triggers
trigger Opportunity on Opportunity (after insert, after update) {

    Map<ID, Date> myMap = new Map<ID, Date>();

    // get all the related accounts
    //
	// create a map from account id to the related opportunity
	//
    Map <Id, Opportunity> mapOpps = new Map <Id, Opportunity> ();

    for (Opportunity o : Trigger.new) {
    	mapOpps.put(o.accountId, o);
    }
    
    Map <Id, Account> mapAccounts = new Map <Id, Account> ([select Id, Service_Start_Date__c from Account where Id in :mapOpps.keySet() ]);

    List<Account> updateAccounts = new List<Account>();
    
	// set the account.service_start_date to the related opportunity.go_live_date
	// if the account.service_start_date is null
	// 
	// set the account owner to the opp.client_service_rep
	// if the opp.StageName is 'Live'
	//
    for (Account a : mapAccounts.values()) {
		Opportunity theOpp = mapOpps.get(a.Id);
		if (theOpp != null && ((a.Service_Start_Date__c == null && theOpp.go_live_date__c != null) || theOpp.StageName == 'Live')) {
			Account theAccount = new Account(Id=a.Id);
			
			if (a.Service_Start_Date__c == null && theOpp.go_live_date__c != null) {
				theAccount.service_start_date__c = theOpp.go_live_date__c;
			}
			if (theOpp.StageName == 'Live') {
				theAccount.ownerid = theOpp.client_service_rep__c;
			}
			
			updateAccounts.add(theAccount);
		}
    	
    }

    if (updateAccounts.size() > 0)  {
	    update updateAccounts;
	}
}

I think this is right, but I didn't compile it.  Let me know how it goes.  Good luck!

Rob Kemper - OpFocus
This was selected as the best answer
Sandra OSandra O
Thank you, Rob! It worked.

can you tell me what you mean by compile?
robdobbyrobdobby
I'm glad it worked!  'Compile' meaning I just used a simple text editor when I wrote the code.  I didn't install the new trigger in a Salesforce org and test it, so it was possible that it had syntax and/or logic errors. 

When you save Apex code using the developer console or an IDE, Salesforce will do a syntax check to make sure that the grammer is correct.

Even if the syntax is correct the logic may be incorrect.  The logic still needs to be validated either with a unit test, by manually testing in the Saleforce org and validating the results, or ideally both.
Sandra OSandra O
Understood! Thakns Rob. 

I did have to fix a  few things, but not bad.  I did test it out and functionality is good. Also ran all tests and it did not create any issues.

Again, thank you!