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
WikWik 

Trigger - Help

Hi,

I have written a Trigger where in i am Preventing duplicate Contact on a Child Account when Same contact appears on the Parent account.

trigger Duplicate on Contact (before insert , before update) {

        set<Id> accIds = new set<Id>();
    set<Id> parentIds = new set<Id>();
    
     for(Contact p :trigger.new){
        accIds.add(p.accountId);
}
map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012600000005J5J']); //add Site record type Id here.
    for(account a:parentAccmap.values()){
        parentIds.add(a.parentId);
        }
        map<Id,Contact> parentPrMap = new map<Id,Contact>();
    list<Contact> prParentlist = [select ID,Email,AccountId, Account.recordtypeId from Contact where AccountId IN:parentIds and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
    for(Contact pr:prParentlist){
        parentPrMap.put(pr.AccountId, pr);
        }
        for(Contact prr:trigger.new){
        if(prr.email!=null && parentAccmap.containsKey(prr.Accountid) && parentPrMap.containsKey(parentAccmap.get(prr.Accountid).ParentId)){
            if(prr.email == parentPrMap.get(parentAccmap.get(prr.Accountid).ParentId).email){
            String baseUrl = URL.getSalesforceBaseUrl().toExternalForm()+'/02Z/e?parentId=';
string errorMsg = '<a style=\'color:1B2BE8\'href="'+baseUrl+ prr.accountid +'"> Please Create a Contact Role  </a>';
                prr.addError('This Contact already exists.'+ errorMsg,false);
            }
        }
    }
}

Can some one help me with logic or modification to the above trigger so that if that contact is present on any of the Child Accounts of the Parent account, error should be thrown.
Best Answer chosen by Wik
Gil GourévitchGil Gourévitch
Ok, so the record type Id inthe trigger is maybe the cause :
I assume that
012600000005J5J = Customer and
012600000005J5I = Site
In the 3rd request, I search in the Sites, but the other condition is on parentId (so the Customer) : try to change the record type id in the 3rd request
from :
list<Contact> prParentlist2 = [select ID,Email,Name,account.parentid, Account.recordtypeId from Contact where account.parentid in :parentIDs and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
to :
list<Contact> prParentlist2 = [select ID,Email,Name,account.parentid, Account.recordtypeId from Contact where account.parentid in :parentIDs and Account.recordtypeId='012600000005J5J']; //add Customer record type Id here.

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users

All Answers

Gil GourévitchGil Gourévitch
Hi,
By using this, 
for(Contact pr:prParentlist){
    parentPrMap.put(pr.AccountId, pr);
}
you get only the last contact on a parent account : the accountid key is the same for all contacts on the same account.
Your test of uniqueness is done only on email ? if so, try use a Map<AccountId, set<email>> and test if a contact email is in the email set of the current account key.


Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !

 
WikWik

thank you for the reply.

But did not get you completely as to where do i need to make change.

Sorry to bother...m naive in triggers

Gil GourévitchGil Gourévitch
Hi,
I did not test it in a real case but, you can try this one :
trigger Duplicate on Contact (before insert , before update) {

    set<Id> accIds = new set<Id>();

    for(Contact p :trigger.new){
        accIds.add(p.accountId);
    }

    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012600000005J5J']); //add Site record type Id here.
    
    map<Id,Set<String>> parentPrMap = new map<Id,Set<String>>();
    list<Contact> prParentlist = [select ID,Email,AccountId, Account.recordtypeId from Contact where AccountId IN:parentAccmap.keySet() and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
    
    
    for(Contact pr:prParentlist){
        if(parentPrMap.get(pr.AccountId) == null){
            parentPrMap.put(pr.AccountId, new Set<String>());
        }
        parentPrMap.get(pr.AccountId).add(pr.email);
    }
    
    for(Contact prr:trigger.new){
        if(
            prr.email!=null 
            && parentAccmap.containsKey(prr.Accountid) 
            && parentPrMap.containsKey(parentAccmap.get(prr.Accountid).ParentId)
        ){
            if(parentPrMap.get(parentAccmap.get(prr.Accountid).ParentId).contains(prr.email)){
                String baseUrl = URL.getSalesforceBaseUrl().toExternalForm()+'/02Z/e?parentId=';
                string errorMsg = '<a style=\'color:1B2BE8\'href="'+baseUrl+ prr.accountid +'"> Please Create a Contact Role  </a>';
                prr.addError('This Contact already exists.'+ errorMsg,false);
            }
        }   
    }
}
Let me know if it do the job, or if you have any error.

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !
 
WikWik
HeyGil,

The trigger that you gave is not working at all. It's not at all preventing duplicates.
Gil GourévitchGil Gourévitch
Ok, I made some (small) corrections :
trigger Duplicate on Contact (before insert, before update) {
    set<Id> accIds = new set<Id>();

    for(Contact p :trigger.new){
        accIds.add(p.accountId);
    }
    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012600000005J5J']); //add Site record type Id here.

    set<ID> parentIds = new set<ID>();
    for(Account acc : parentAccmap.values()){
        parentIds.add(acc.parentId);
    }
    
    map<Id,Set<String>> parentPrMap = new map<Id,Set<String>>();
    list<Contact> prParentlist = [select ID,Email,Name,AccountId, Account.recordtypeId from Contact where AccountId IN:parentIds and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
        
    for(Contact pr:prParentlist){
        if(parentPrMap.get(pr.AccountId) == null){
            parentPrMap.put(pr.AccountId, new Set<String>());
        }
        parentPrMap.get(pr.AccountId).add(pr.email);
    }
    
    for(Contact prr:trigger.new){
        if(
            prr.email!=null 
            && parentAccmap.containsKey(prr.Accountid) 
            && parentPrMap.containsKey(parentAccmap.get(prr.Accountid).ParentId)
        ){
            if(parentPrMap.get(parentAccmap.get(prr.Accountid).ParentId).contains(prr.email)){
                String baseUrl = URL.getSalesforceBaseUrl().toExternalForm()+'/02Z/e?parentId=';
                string errorMsg = '<a style=\'color:1B2BE8\'href="'+baseUrl+ prr.accountid +'"> Please Create a Contact Role  </a>';
                prr.addError('This Contact already exists.'+ errorMsg,false);
            }
        }   
    }
}
Let me know if you have any error.

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !
 
WikWik

Working but only for Parent. i.e. it is checking duplicates based on Parent Record only , as my initial trigger did.

If a dupliate is present another child account of the same parent account, in that case this trigger does not prevent duplicates

Gil GourévitchGil Gourévitch
Ok, I did not understood that, sorry...
change the line :
list<Contact> prParentlist = [select ID,Email,Name,AccountId, Account.recordtypeId from Contact where AccountId IN:parentIds and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
to :
list<Contact> prParentlist = [select ID,Email,Name,AccountId, Account.recordtypeId from Contact where (AccountId IN:parentIds or account.parentid in :parentIds) and Account.recordtypeId='012600000005J5I'
]; //add Customer record type Id here.
so the query will search in parent, or in all accounts witch have the same parentId = brothers
That would do the trick.

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !
WikWik
duplicates are still being allowed on the Child Account level. it prevents duplicates if email is used on Parent else does not
Gil GourévitchGil Gourévitch
Ok, to prevent that, you should use this  :
trigger Duplicate on Contact (before insert, before update) {
    set<Id> accIds = new set<Id>();

    for(Contact p :trigger.new){
        accIds.add(p.accountId);
    }
    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012600000005J5J']); //add Site record type Id here.

    set<ID> parentIds = new set<ID>();
    for(Account acc : parentAccmap.values()){
        parentIds.add(acc.parentId);
    }
    
    map<Id,Set<String>> parentPrMap = new map<Id,Set<String>>();
    list<Contact> prParentlist = [select ID,Email,Name,AccountId, Account.recordtypeId from Contact where AccountId IN:parentIDs and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
    for(Contact pr:prParentlist){
        if(parentPrMap.get(pr.AccountId) == null){
            parentPrMap.put(pr.AccountId, new Set<String>());
        }
        parentPrMap.get(pr.AccountId).add(pr.email);
    }

    list<Contact> prParentlist2 = [select ID,Email,Name,account.parentid, Account.recordtypeId from Contact where account.parentid in :parentIDs and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
    for(Contact pr:prParentlist2){
        if(parentPrMap.get(pr.account.parentid) == null){
            parentPrMap.put(pr.account.parentid, new Set<String>());
        }
        parentPrMap.get(pr.account.parentid).add(pr.email);
    }
    system.debug(parentPrMap);
    
    for(Contact prr:trigger.new){
        if(
            prr.email!=null
            && parentAccmap.containsKey(prr.Accountid)
            && parentPrMap.containsKey(parentAccmap.get(prr.Accountid).ParentId)
        ){
            if(parentPrMap.get(parentAccmap.get(prr.Accountid).ParentId).contains(prr.email)){
                String baseUrl = URL.getSalesforceBaseUrl().toExternalForm()+'/02Z/e?parentId=';
                string errorMsg = '<a style=\'color:1B2BE8\'href="'+baseUrl+ prr.accountid +'"> Please Create a Contact Role  </a>';
                prr.addError('This Contact already exists.'+ errorMsg,false);
            }
        }   
    }
}

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !
 
WikWik

no success yet gill

 

Gil GourévitchGil Gourévitch
I tried it on a dev instance, and it prevent duplicates like that :
- parent account : email_parent@email.com
- child account : email_child@email.com
- on child 2 (child of parent account) I try to create email_child@email.com -> error

did you try with the correct record type ? (the request takes it into account)

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users !
 
WikWik

yes i am doing the same thing but in case of child records it is allowing duplicates

child account : email_child@email.com

child 2 ( chil of parent account) email: email_child@email.com  --- no error , but it should be throwing error

Gil GourévitchGil Gourévitch
I tried with my ids for the recordtypeid filter, and it throws an error when I try to create the 2nd duplicate...
Are we doing the same thing ?
User-added image
When I try to insert the contact on child 2 account, I get an error.
And if I try to insert a contact on child 2 with the email : Email_parent@email.com, I also get an error.

did you try with the correct record type ids ?
are you sure that all the accounts are of the correct recordtype id ?

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users
WikWik

yup i am trying the same thing.
If a contact is on parent and if i try to duplicate it on a child account, the trigger works and prevents the duplicate.
But if a contact exists on the child and i try to duplicate this contact on another child of the same parent, then the trigger does ot work and does not throw the error. it should be throwing error even then.

i checked the record type ids, they are correct. The Customer is the Parent Account and the Site is the child account

Gil GourévitchGil Gourévitch
Ok, so the record type Id inthe trigger is maybe the cause :
I assume that
012600000005J5J = Customer and
012600000005J5I = Site
In the 3rd request, I search in the Sites, but the other condition is on parentId (so the Customer) : try to change the record type id in the 3rd request
from :
list<Contact> prParentlist2 = [select ID,Email,Name,account.parentid, Account.recordtypeId from Contact where account.parentid in :parentIDs and Account.recordtypeId='012600000005J5I']; //add Customer record type Id here.
to :
list<Contact> prParentlist2 = [select ID,Email,Name,account.parentid, Account.recordtypeId from Contact where account.parentid in :parentIDs and Account.recordtypeId='012600000005J5J']; //add Customer record type Id here.

Hope this helps
Gil

Question Solved ? Please mark as the best answer to help other users
This was selected as the best answer
Gil GourévitchGil Gourévitch
Hi,
Did you solved your problem ?
WikWik
Thanx a lot.
It did.

Just figuring out  a case where the duplicates will not only be checked on Email but Phone, Name as well