+ Start a Discussion
Mario CMario C 

Help with simple trigger on contact

I can't get the following trigger to update the acount!

Can you pleas help me?
 
trigger UpdateMembershipLevelOnAccount on Contact (after update) {

	for(Contact con : Trigger.New) {
	List<Contact> conList;
	List<Contact> gm;
	List<Contact> sm;
	List<Contact> bm;
	String contactMembLevel;
	String accountMembLevel;

		conList = [Select ID, Member_Level__c, Account.Membership_Level_Text__c FROM Contact WHERE Account.Id = :con.Account.Id];
		
		if(conList.Size() <2 ){
			accountMembLevel = contactMembLevel;
		}

		else if(conList.Size() >1 ){


		for(Contact c: conList){
			contactMembLevel = con.Member_Level__c;
			accountMembLevel = con.Account.Membership_Level_Text__c;


			if(c.Member_Level__c == 'Gold'){
				gm.add(c);
				accountMembLevel = 'Gold';
			}
			else if(c.Member_Level__c == 'Silver'){
				sm.add(c);
				if(gm.size() <1 && sm.size() >0){
				accountMembLevel = 'Silver';
		}
					else {
				
				bm.add(c);
				accountMembLevel= 'Black';
			}
				}
				
				}
				
				}
}
}



 
Best Answer chosen by Mario C
AshishkAshishk
Please try below...
trigger UpdateMembershipLevelOnAccount on Contact (after insert,after update) {
	
		
	List<id> lstAccountIds=new List<id>();	
	for(Contact con : Trigger.New) {					
			lstAccountIds.add(con.AccountId);
	}
	
	List<Contacts> contactLst=[Select id,Member_Level__c from contact where AccountId in:lstAccountIds];
	Set<id> accountIDGoldSet=new Set<id>();	
	Set<id> accountIDSilverSet=new Set<id>();	
	for(Contact con : contactLst) {
		if(con.Member_Level__c == 'Gold'){
			accountIDGoldSet.add(con.AccountId);				
		}
		else if(con.Member_Level__c == 'Silver'){
			accountIDSilverSet.add(con.AccountId)
		}
	}
	List<Account> lstAccountToUpdate=new List<Account>();
	Map<id,Account> mapAccounts=Map<id,Account>([Select id, Membership_Level_Text__c from account where id in:lstAccountIds]);
	for(Account a:mapAccounts.values()){
		if(accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='Gold';
			lstAccountToUpdate.add(a);
		}
		if(accountIDSilverSet.contains(a.id) && !accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='Silver';
			lstAccountToUpdate.add(a);
		}
		if(!accountIDSilverSet.contains(a.id) && !accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='';
			lstAccountToUpdate.add(a);
		}		
	}
	
	if(!lstAccountToUpdate.isEmpty() && lstAccountToUpdate.size()>0)
		update lstAccountToUpdate;
	
}

Hope this works.

Thanks

All Answers

AshishkAshishk
What you want to update on account? Field names and give logic requriment, I can help you.

Thanks
Mario CMario C
if on any of the contacts of an account  member level is gold, the related account membership level field has to be populated with Gold
if on any of the contacts of an account there is not any with member level gold, but there is a silver then the related account membership level field has to be populated with Silver
if on any of the contacts of an account there is not any with member level gold or silver, the related account membership level has to be populated with Black (black is the default contact member level value) 
AshishkAshishk
Try this:-
trigger UpdateMembershipLevelOnAccount on Contact (after insert,after update) {
	
	List<Account> lstAccountToUpdate=new List<Account>();
	
	List<id> lstAccountIds=new List<id>();	
	for(Contact con : Trigger.New) {
		if(con.Member_Level__c == 'Gold' || con.Member_Level__c == 'Silver')			
			lstAccountIds.add(con.AccountId);
	}
	
	Map<id,Account> mapAccounts=Map<id,Account>([Select id, Membership_Level_Text__c  from account where id in:lstAccountIds]);
	for(Contact con : Trigger.New) {
		Account a=mapAccounts.get(con.AccountId);
		if(con.Member_Level__c == 'Gold'){
			a.Membership_Level_Text__c='Gold';
			
		}
		else if(con.Member_Level__c == 'Silver'){
			a.Membership_Level_Text__c='Silver';
		}
		lstAccountToUpdate.add(a);
	}
	if(!lstAccountToUpdate.isEmpty())
		update lstAccountToUpdate;
	
}
Hope this works,
Thanks
 
Mario CMario C
It works but it has some issues. When I change the value of a contact member value, I get this error:
UpdateMembershipLevelOnAccount: execution of AfterUpdate caused by: System.ListException: DML statement found null SObject at position 0 Trigger.UpdateMembershipLevelOnAccount: line 24, column 1
AshishkAshishk
Change below line:-
if(!lstAccountToUpdate.isEmpty())
		update lstAccountToUpdate;
with
if(!lstAccountToUpdate.isEmpty() && lstAccountToUpdate.size()>0)
		update lstAccountToUpdate;


 
AshishkAshishk
Corrected Version:-
trigger UpdateMembershipLevelOnAccount on Contact (after insert,after update) {
	
	List<Account> lstAccountToUpdate=new List<Account>();
	
	List<id> lstAccountIds=new List<id>();	
	for(Contact con : Trigger.New) {
		if(con.Member_Level__c == 'Gold' || con.Member_Level__c == 'Silver')			
			lstAccountIds.add(con.AccountId);
	}
	
	Map<id,Account> mapAccounts=Map<id,Account>([Select id, Membership_Level_Text__c  from account where id in:lstAccountIds]);
	for(Contact con : Trigger.New) {
		if(mapAccounts.containsKey(con.AccountId)){
			Account a=mapAccounts.get(con.AccountId);
			if(con.Member_Level__c == 'Gold'){
				a.Membership_Level_Text__c='Gold';
				
			}
			else if(con.Member_Level__c == 'Silver'){
				a.Membership_Level_Text__c='Silver';
			}
			lstAccountToUpdate.add(a);
		}
	}
	if(!lstAccountToUpdate.isEmpty() && lstAccountToUpdate.size()>0)
		update lstAccountToUpdate;
	
}

 
Mario CMario C
Hi Ashishk,

Thanks for your help so far. 

The account membership level should be Gold if at least 1 contact of the same account has member_level__c = gold. Similarly, the account membership level should be Silver if at least 1 contact of the same account has member_level__c = Silver and none of the contacts of the same account are Member Level = Gold. If none of the contact of same account have member level =  gold or silver, the account membership level should be set to black. 

As you can see, in my original code, I've divided the account contacts in 3 lists based on contact member level; the size of each list will indicate the contacts of the account are gold, silver and/or black.

 
AshishkAshishk
Please try below...
trigger UpdateMembershipLevelOnAccount on Contact (after insert,after update) {
	
		
	List<id> lstAccountIds=new List<id>();	
	for(Contact con : Trigger.New) {					
			lstAccountIds.add(con.AccountId);
	}
	
	List<Contacts> contactLst=[Select id,Member_Level__c from contact where AccountId in:lstAccountIds];
	Set<id> accountIDGoldSet=new Set<id>();	
	Set<id> accountIDSilverSet=new Set<id>();	
	for(Contact con : contactLst) {
		if(con.Member_Level__c == 'Gold'){
			accountIDGoldSet.add(con.AccountId);				
		}
		else if(con.Member_Level__c == 'Silver'){
			accountIDSilverSet.add(con.AccountId)
		}
	}
	List<Account> lstAccountToUpdate=new List<Account>();
	Map<id,Account> mapAccounts=Map<id,Account>([Select id, Membership_Level_Text__c from account where id in:lstAccountIds]);
	for(Account a:mapAccounts.values()){
		if(accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='Gold';
			lstAccountToUpdate.add(a);
		}
		if(accountIDSilverSet.contains(a.id) && !accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='Silver';
			lstAccountToUpdate.add(a);
		}
		if(!accountIDSilverSet.contains(a.id) && !accountIDGoldSet.contains(a.id)){
			a.Membership_Level_Text__c='';
			lstAccountToUpdate.add(a);
		}		
	}
	
	if(!lstAccountToUpdate.isEmpty() && lstAccountToUpdate.size()>0)
		update lstAccountToUpdate;
	
}

Hope this works.

Thanks
This was selected as the best answer
AshishkAshishk
Is this working? If yes please close this.

Thanks,
Ashish
Mario CMario C
Hi Ashish,

I am getting the following when I create a new contact:
UpdateMembershipLevelOnAccount: execution of AfterInsert caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Contact.AccountId Trigger.UpdateMembershipLevelOnAccount: line 14, column 1
AshishkAshishk
Change line no 9 to:-

List<Contacts> contactLst=[Select id,Member_Level__c,AccountId from contact where AccountId in:lstAccountIds];