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
John Neilan 18John Neilan 18 

Need Help With addError Statement

Hello,

I have a trigger where the 1st part is desiged to loop through custom object records of a Contact and prevent users from entering duplicate records for each account.  I have a statement that checks a map against the record being inserted/changed. When I look at my logs, I see that the IF statement returns a FALSE result, so the trigger should move on, but it is still throwing the addError message.  Does anyone know why this might be hapening?  The line is question is Line 48 below.
 
trigger UpdateAcctVIP on VIP_Type__c (after insert, after update, after delete){

Set<Id> acctIds = new Set<ID>();
Set<Id> contIds = new Set<ID>();
Set<String> vipTypes = new Set<String>();
    
Map<VIP_Type__c, VIP_Type__c> contactTypeMap = new Map<VIP_Type__c, VIP_Type__c>();
// Get all the Account & Contact Ids in the Set 

	if (Trigger.isDelete) {
		for(VIP_Type__c vip : Trigger.old){
			acctIds.add(vip.Account__c);
            contIds.add(vip.Contact__c);
		    VIP_Type__c key = new VIP_Type__c(Contact__c=vip.Contact__c, Account__c=vip.Account__c, VIP_Type__c=vip.VIP_Type__c);
		}
	}
	else{

    for(VIP_Type__c vip : Trigger.new) {
    	acctIds.add(vip.Account__c);
    	contIds.add(vip.Contact__c);
        vipTypes.add(vip.VIP_Type__c);
    	VIP_Type__c key = new VIP_Type__c(Contact__c=vip.Contact__c, Account__c=vip.Account__c, VIP_Type__c=vip.VIP_Type__c);
system.debug('@@@### - Key Check:  '+key);
system.debug('@@@### - vip Check:  '+vip);
system.debug('@@@### - 1st Map Check:  '+contactTypeMap.put( key, vip ));
system.debug('@@@### - 2nd Map Check:  '+contactTypeMap.get( key ));
system.debug('@@@### - 2nd Map Check:  '+contactTypeMap);

	        if(contactTypeMap.put( key, vip ) != null) {
	       		contactTypeMap.get( key ).addError( 'This type already exits for this Contact' );
    		}
     }
	 }

List<VIP_Type__c> vipRecs = [SELECT Id,Account__c,Contact__c,VIP_Type__c
                            FROM VIP_Type__c
                            WHERE Contact__c = :contIds AND Account__c = :acctIds AND ID NOT IN:trigger.new];

//Check for VIP Types already entered for Contact
for(VIP_Type__c vip: vipRecs) {
system.debug('@@@### - Check for Types:  '+vipRecs);
    VIP_Type__c key = new VIP_Type__c(Contact__c=vip.Contact__c, Account__c=vip.Account__c, VIP_Type__c=vip.VIP_Type__c);
system.debug('@@@### - Check for Types-key:  '+key);
system.debug('@@@### - Check contactTypeMap:  '+contactTypeMap);
system.debug('@@@### - Check contactTypeMap (key):  '+contactTypeMap.containsKey(key));

    if(contactTypeMap.containsKey(key)) {
        contactTypeMap.get(key).addError('This Type already exists for this Contact');
    }
}
    

// Query the Accounts
		List<Account> acct = new List<Account>();

// Use the VIP Types to get all the related Types for the Account 
			acct = [SELECT Id, VIP_Types__c,(Select VIP_Type__c FROM VIP_Types__r) 
					FROM Account 
					WHERE Id in :acctIds]; 

// Iterate over each Account and VIP record 
			for(Account a : acct){ 
				a.VIP_Types__c = ''; 

				for(VIP_Type__c vip: a.VIP_Types__r){ 

					if(!a.VIP_Types__c.contains(vip.VIP_Type__c) || a.VIP_Types__c == ''){ // Check if the Type is already in the Account Field. if not add it otherwise skip 

					a.VIP_Types__c += vip.VIP_Type__c + '; '; 
					} 
				} 
			} 
// Update the Account 
		update acct; 
}

 
Best Answer chosen by John Neilan 18
Abhishek BansalAbhishek Bansal
Hi John,

Can you please use the below code which meets your requirement:
trigger UpdateAcctVIP on VIP_Type__c (after insert, after update, after delete){

	Set<Id> acctIds = new Set<ID>();
	Set<Id> contIds = new Set<ID>();
	map<Id, set<VIP_Type__c>> contact_type_map = new map<Id, set<VIP_Type__c>>();

// Get all the Account & Contact Ids in the Set 
	if (Trigger.isDelete) {
		for(VIP_Type__c vip : Trigger.old){
			acctIds.add(vip.Account__c);
            contIds.add(vip.Contact__c);
//            contact_type_map.put(vip.Contact__c, new set<VIP_Type__c>());
		}
	}
	else{
        for(VIP_Type__c vip : Trigger.new){
			acctIds.add(vip.Account__c);
            contIds.add(vip.Contact__c);
//            contact_type_map.put(vip.Contact__c, new set<VIP_Type__c>{vip});
	}
    }
 List<VIP_Type__c> vipRecs = [SELECT Id,Account__c,Contact__c,VIP_Type__c
                                    FROM VIP_Type__c
                                    WHERE Contact__c in:contIds];

    Map<Id,set<string>> existingTypeMap = new Map<Id,set<string>>();

    for (VIP_Type__c type: vipRecs)
    {
        set<string> existingTypes = new set<string>();
        if(existingTypeMap.containsKey(type.contact__c))
        {
            existingTypes = existingTypeMap.get(type.contact__c);
        }
        existingTypes.add(type.VIP_Type__c);
        existingTypeMap.put(type.contact__c,existingTypes);
    }



    for (VIP_Type__c type : trigger.new)
    {
        if (existingTypeMap.containsKey(type.contact__c))
        {
            if (existingTypeMap.get(type.contact__c).contains(type.VIP_Type__c))
            {
                trigger.newMap.get(type.Id).addError('This Type already exists for this Contact');
            }
            else
            {
                Set<string> existingTypes = existingTypeMap.get(type.contact__c);
                existingTypes.add(type.VIP_Type__c);
                existingTypeMap.put(type.contact__c,existingTypes);
            }

        }
    }
    
// Query the Accounts
		List<Account> acct = new List<Account>();

// Use the VIP Types to get all the related Types for the Account 
			acct = [SELECT Id, VIP_Types__c,(Select VIP_Type__c FROM VIP_Types__r) 
					FROM Account 
					WHERE Id in :acctIds]; 

// Iterate over each Account and VIP record 
			for(Account a : acct){ 
				a.VIP_Types__c = ''; 

				for(VIP_Type__c vip: a.VIP_Types__r){ 

					if(!a.VIP_Types__c.contains(vip.VIP_Type__c) || a.VIP_Types__c == ''){ // Check if the Type is already in the Account Field. if not add it otherwise skip 

					a.VIP_Types__c += vip.VIP_Type__c + '; '; 
					} 
				} 
			} 
// Update the Account 
		update acct; 
}

Let me know if there is any issue.

Thanks,
Abhishek Bansal.​​​​​​​

All Answers

Abhishek BansalAbhishek Bansal
Hi John,

Can you please use the below code which meets your requirement:
trigger UpdateAcctVIP on VIP_Type__c (after insert, after update, after delete){

	Set<Id> acctIds = new Set<ID>();
	Set<Id> contIds = new Set<ID>();
	map<Id, set<VIP_Type__c>> contact_type_map = new map<Id, set<VIP_Type__c>>();

// Get all the Account & Contact Ids in the Set 
	if (Trigger.isDelete) {
		for(VIP_Type__c vip : Trigger.old){
			acctIds.add(vip.Account__c);
            contIds.add(vip.Contact__c);
//            contact_type_map.put(vip.Contact__c, new set<VIP_Type__c>());
		}
	}
	else{
        for(VIP_Type__c vip : Trigger.new){
			acctIds.add(vip.Account__c);
            contIds.add(vip.Contact__c);
//            contact_type_map.put(vip.Contact__c, new set<VIP_Type__c>{vip});
	}
    }
 List<VIP_Type__c> vipRecs = [SELECT Id,Account__c,Contact__c,VIP_Type__c
                                    FROM VIP_Type__c
                                    WHERE Contact__c in:contIds];

    Map<Id,set<string>> existingTypeMap = new Map<Id,set<string>>();

    for (VIP_Type__c type: vipRecs)
    {
        set<string> existingTypes = new set<string>();
        if(existingTypeMap.containsKey(type.contact__c))
        {
            existingTypes = existingTypeMap.get(type.contact__c);
        }
        existingTypes.add(type.VIP_Type__c);
        existingTypeMap.put(type.contact__c,existingTypes);
    }



    for (VIP_Type__c type : trigger.new)
    {
        if (existingTypeMap.containsKey(type.contact__c))
        {
            if (existingTypeMap.get(type.contact__c).contains(type.VIP_Type__c))
            {
                trigger.newMap.get(type.Id).addError('This Type already exists for this Contact');
            }
            else
            {
                Set<string> existingTypes = existingTypeMap.get(type.contact__c);
                existingTypes.add(type.VIP_Type__c);
                existingTypeMap.put(type.contact__c,existingTypes);
            }

        }
    }
    
// Query the Accounts
		List<Account> acct = new List<Account>();

// Use the VIP Types to get all the related Types for the Account 
			acct = [SELECT Id, VIP_Types__c,(Select VIP_Type__c FROM VIP_Types__r) 
					FROM Account 
					WHERE Id in :acctIds]; 

// Iterate over each Account and VIP record 
			for(Account a : acct){ 
				a.VIP_Types__c = ''; 

				for(VIP_Type__c vip: a.VIP_Types__r){ 

					if(!a.VIP_Types__c.contains(vip.VIP_Type__c) || a.VIP_Types__c == ''){ // Check if the Type is already in the Account Field. if not add it otherwise skip 

					a.VIP_Types__c += vip.VIP_Type__c + '; '; 
					} 
				} 
			} 
// Update the Account 
		update acct; 
}

Let me know if there is any issue.

Thanks,
Abhishek Bansal.​​​​​​​
This was selected as the best answer
John Neilan 18John Neilan 18
Thanks Abhishek!  It was thowing the error message for anything entered, but I added :
AND NOT IN:trigger.new
to the List and it solved the issue.  Thanks so much for your help!!