0

I have created a trigger on a custom object that is going to be used to store Lead data, when this information is initially inserted to the object the trigger creates a Map of current Lead and Opportunity information (Company Name, Postcode, Landline Phone). This information is then compared to the data being inserted to the custom object and if a Match is found I want the ID's for every match that is found from Leads and Opportunities to be inserted to a text field on the object.

Currently my code is only able to return a single ID when a match is found and I am having trouble figuring out a way to get ALL of the ID's matched. Here is my current code:

trigger LeadDuplicateChecker on Data_Vault__c (before insert, before update) {

    //Map Company/Postcode/Phone to ID
    Map<String,Id> comparisonMap = new Map<String,Id>();

    //Company
    for(Lead l : [Select Id, Company, Postcode__c, Landline_Phone__c From Lead Where isConverted = FALSE and Company != null]){

        IF(l.Company != null){
        comparisonMap.put(l.Company.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), l.Id);
        }
        IF(l.Postcode__c != null){
        comparisonMap.put(l.Postcode__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), l.Id);
        }
        IF(l.Landline_Phone__c != null){
        comparisonMap.put(l.Landline_Phone__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), l.Id);
        }

    }

    for(Opportunity o : [Select Id, Name, Postcode__c, Landline_Phone__c From Opportunity Where StageName IN ('To Call Back','Quote Given','On Stop','In Contract - Diarised') AND Name != null]){

        IF(o.Name != null){
        comparisonMap.put(o.Name.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), o.Id);
        }
        IF(o.Postcode__c != null){
        comparisonMap.put(o.Postcode__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), o.Id);
        }
        IF(o.Landline_Phone__c != null){
        comparisonMap.put(o.Landline_Phone__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_',''), o.Id);
        }

    }
    system.debug('Map Keyset: ' +comparisonMap.keySet() );


    //Comparison loop    
    for(Data_Vault__c d : Trigger.New){

        //Set Matching Fields to blank before performing comparison
        d.Company_Match__c            =    '';
        d.Phone_Match__c              =    '';
        d.Postcode_Match__c           =    '';
        d.Record_Company_Match__c     =    '';
        d.Record_Phone_Match__c       =    '';
        d.Record_Postcode_Match__c    =    '';

        //Company
        IF(d.Company_Name__c != null){
            If(comparisonMap.containsKey(d.Company_Name__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') )){

                d.Company_Match__c = 'Company Match Found';
                d.Record_Company_Match__c = comparisonMap.get(d.Company_Name__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') );

            }
        }

        //Postcode
        IF(d.Postcode__c != null){
            If(comparisonMap.containsKey(d.Postcode__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') )){

                d.Postcode_Match__c = 'Postcode Match Found';
                d.Record_Postcode_Match__c = comparisonMap.get(d.Postcode__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') );

            }
        }

        //Phone
        IF(d.Phone__c != null && d.Phone__c != 'TPS'){
            If(comparisonMap.containsKey(d.Phone__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') )){ 

                d.Phone_Match__c = 'Phone Match Found';
                d.Record_Phone_Match__c = comparisonMap.get(d.Phone__c.toLowerCase().replace(' ','').replace('-','').replace('~','').replace('!','').replace('@','').replace('#','').replace('$','').replace('%','').replace('^','').replace('&','').replace('_','') );

            }
        }
    }

}

Would really appreciate any help/guidance on a solution to this!

3
  • It is a bit unclear what you are asking. Do you want your comparisonMap to store a List of Ids for every key? eg: Map<String, List<Id>>
    – BarCotter
    Commented Jun 23, 2015 at 10:03
  • I am a bit unexperienced when it comes to Maps so bare with me but my current comparisonMap contains all of the values of the fields I am comparing against my custom object (Company Name, Postcode, Phone) as the key and the values are the Id's of the Lead/Opp where the match was found.
    – Liam
    Commented Jun 23, 2015 at 12:25
  • cont. I am attempting to show the Ids of every Lead/Opp on the Record_Company_Match__c / Record_Postcode_Match__c / Record_Phone_Match__c fields where a match has been found but I am struggling to figure out a way to do this. Hopefully this makes sense.
    – Liam
    Commented Jun 23, 2015 at 12:32

1 Answer 1

2

Maps have a "key" and a "value". Its very important that the "key" be unique. If it isn't, it will get overwritten. For a unique key, there can only be one value in the map. That value can be an object which contains fields. E.G.:

map<Id,Account> AcctMap = new map([select Id, name, shipping street, shipping state, shipping zip WHERE name IN :listNames]);

The issue that you're dealing with is that in a beforeInsert trigger, you don't have an Id's for your records in Trigger.new if you put them in a map even though they're also in a map called Trigger.newmap. But, the Id's that you've queried, can be put in a map just as I've outlined above and be sorted on for matches which is exactly what you need to do. When a match is found, you can add the Id to a Set or List. Set is preferable so you don't need to concern yourself with list exceptions due to duplicate Id's.

That means your trigger needs to look more like this:

trigger LeadDuplicateChecker on Data_Vault__c (before insert, before update) {

    Map<Id,Lead> leadMap = new Map<Id,Lead>();
    Map<Id,Opportunity> oppMap = new Map<Id,Opportunity>();

    //Company - It appears here that you want to test for all 3 company fields being a match?

    leadMap = new Map<Id,Lead>([Select Id, Company, Postcode__c, Landline_Phone__c From Lead Where isConverted = FALSE and Company != null]);
    for(Lead l : comparisonMap1){

    oppMap = new Map<Id,Opportunity([Select Id, Name, Postcode__c, Landline_Phone__c From Opportunity Where StageName IN ('To Call Back','Quote Given','On Stop','In Contract - Diarised') AND Name != null]);

    // In the above, Name is the name of the Opportunity, NOT the name of the Account. 
    // I strongly suspect that what you wanted was the Account.Name      

Now that you have these, you can run your comparisons directly without concatenating them and putting them a map of ID, string as you were doing previously. However, you'll need to run the leads separately from the opportunities since they're on different objects.

Again, I don't know what your match criteria is going to be (all three fields, 2 of 3?, etc), so you'll need to reflect that in your code. Obviously, a postal code by itself is rather irrelevant. The same could be said for a phone number. If they're not in the context of a company name, they probably don't mean much since phone numbers change and postal codes are assigned to large areas. BTW, an email address would be more definitive.

For each record in trigger.new, you'll need to do a comparison for Name. If you find one, then and only then would I check for the other values if it were me, but I'll leave that logic up to you. If found, then you'll have the ID of the record you can put to your map or set, depending on the form you need to track it in.

Just to be clear, your compare loops should look something like this:

for(Data_Vault__c d : Trigger.New){
   if(d.Company_Name__c != null){
      for(ID lId:leadMap.keyset()){
         if(d.Company_Name__c.toLowerCase() == leadMap.get(lId).Company.toLowerCase()){
             // add your logic here to collect Ids, continue checking other fields in 
             // nested if statements, put Id or add to set, break from loop, etc
         }
      }
   }
}
1
  • Sorry for the late follow-up but I have begun to implement this logic into my trigger and my initial tests are working fine! Still have a lot to implement and test but its looking good so far so thank you very much for your post, very helpful.
    – Liam
    Commented Jul 6, 2015 at 15:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .