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
Pankaj Vithal 13Pankaj Vithal 13 

Copy a trigger from contacts object and replicate it on Leads object - need developer help

Guys, I am an Admin who needs help from a developer. I have an apex trigger that was written and implemented by a contractor. It is on Contacts object. What is does is assign the contact to an owner based on the first three digits of the postal code. I need to have the same assignment triggger on Leads object.
Best Answer chosen by Pankaj Vithal 13
Ryan GreeneRyan Greene
I updated your test below. Create a new class in your sandbox with the name LeadUpdateOwnerTest and paste in the code. As long as there's no problems click run test on this one and also on the test class for Utils. Make sure they both complete and have at least 75% converage. Then create an outbound change set with all 4 codes in it, the Trigger, Utils Class, and the test for both. When you deploy click run specified tests and run the two that are in the change set. Let me know if you need more help deploying! Good luck!

Updated Test:
@isTest(SeeAllData=true)
public class LeadUpdateOwnerTest{
    
    static testMethod void testLeadUpdateOwner() {
        set<string> setPC=new set<string>();
        setPC.Add('M4X');
        User_Territory_Map__c um= new User_Territory_Map__c(POSTAL_CODE__c='M4X', Assigned_User__c=UserInfo.GetUserId());
        insert um;
        
        Lead[] ld = new Lead[] {            
            new Lead(LastName = 'Test Lead1',Street='100 King St W',City='Toronto',State='ON',PostalCode='M4X 1A1',Country='Canada'),
                new Lead(LastName = 'Test Lead2',Street='100 King St W',City='Toronto',State='ON',PostalCode='M4X 1A1',Country='Canada')};
                    
                    insert ld;        
        ld[0].PostalCode='M4X 1A3';
        ld[1].PostalCode='M4X 1A2';
        update ld;       
    }
}

 

All Answers

Ryan GreeneRyan Greene
You should be able to copy it to a new trigger and replace all the Contant lookups to Lead instead. Post the code too if you'd like further help.
Pankaj Vithal 13Pankaj Vithal 13
Couple of things I'd like to convey here:

I once tried to write an apex trigger not allowing a particular user to post on chatter feed following instruction from helpful people like you just like an amateur. i was able to make that code work on sandbox but when i moved to production, it gave errors like not enough code coverage and missing test class at which point i just gave up. I though i need to start learning this developer thing from beginning to deal with it.

so, that are the kind of things I'd need some help with to successfully implement this code.

CODE:


Purpose: This trigger changes ownership of contact as per mapping defined in user territory mapping object.
    If a contact is being created and [override contact owner] is unchecked, then change contact owner to user as defined in territory mapping object.
    If a contac tis beign created or updated and is set to active/inactive then append/remove  "_do not use" text from contact name.
   Original Date: Mar 24, 2017
 

*/
trigger ContactUpdateOwner on Contact (before insert, before update) {
if(Utils.firstRun || Test.isRunningTest()){
    Utils.firstRun=false;
    
    set<string> setPC= new set<string>();
    if(Trigger.isBefore && Trigger.isInsert){
        for(Contact c : Trigger.New){
            if(c.MailingPostalCode != null && !c.Override_Owner_Rules__c){
                setPC.Add(c.MailingPostalCode.left(3).trim());
            }
            
            // If contact status is being set then change contact name as well.
            if(c.Status__c != null ){
                if(c.Status__c=='Inactive'){
                    c.LastName=c.LastName + '_DoNotUse';
                } else if(c.Status__c=='Active') {
                    if(c.LastName.contains('_DoNotUse')){ 
                        c.LastName=c.LastName.remove('_DoNotUse');
                    }   
                }
            }
            
        }
    }
   
    if(Trigger.isBefore && Trigger.isUpdate){
        for(Contact c : Trigger.New){
            // If a contacts postal code was changed and not set to override rules
            if(c.MailingPostalCode != null && Trigger.OldMap.get(c.id).MailingPostalCode != c.MailingPostalCode && !c.Override_Owner_Rules__c){
                setPC.Add(c.MailingPostalCode.left(3).trim());
            }
            
            // If contact status is being changed then change contact name as well.
            if(c.Status__c != null && Trigger.OldMap.get(c.id).Status__c != c.Status__c){
                if(c.Status__c=='Inactive'){
                    c.LastName=c.LastName + '_DoNotUse';
                } else if(c.Status__c=='Active') {
                    if(c.LastName.contains('_DoNotUse')){ 
                        c.LastName=c.LastName.remove('_DoNotUse');
                    }   
                }
            }
        }
    }
    
    if(setPC.size()>0){
        List<contact> lstCon= new List<contact>();
        Map<string, Id> mapPCOwnerId = Utils.GetPCOwnerIdMap(setPC);
        if(Trigger.isBefore && Trigger.isInsert){
            for(Contact c : Trigger.New){
                if(c.MailingPostalCode != null && !c.Override_Owner_Rules__c){
                    if(mapPCOwnerId.containsKey(c.MailingPostalCode.left(3).trim())){
                        c.OwnerId=mapPCOwnerId.get(c.MailingPostalCode.left(3).trim());
                        lstCon.Add(c);
                    }
                }
            }
        }
        
        if(Trigger.isBefore && Trigger.isUpdate){
            for(Contact c : Trigger.New){
                if(c.MailingPostalCode != null && Trigger.OldMap.get(c.id).MailingPostalCode != c.MailingPostalCode && !c.Override_Owner_Rules__c){
                    if(mapPCOwnerId.containsKey(c.MailingPostalCode.left(3).trim())){
                        c.OwnerId=mapPCOwnerId.get(c.MailingPostalCode.left(3).trim());                       
                        lstCon.Add(c);
                    }
                }
            }
        }
    }
}
}
Pankaj Vithal 13Pankaj Vithal 13
BTW THANKS @RYAN. REALLY OWE YOU ONE IF WE GET THIS THROUGH
Ryan GreeneRyan Greene
Pankaj,
That's what the community is here for!
The process to develop Apex is create it in the sandbox, get it all working, write a test, and deploy to Production. The tests is where you got stuck. See if you can find the test for the code you posted. As a developer I always prefix my tests with Test_, see if your contractor did the same.
I'll update this code for you this afternoon to reflect Lead instead of Contact.

ALSO, there is custom field (Override_Owner_Rules__c) in your Contact object which may not be in the Lead. Could you see if that field exists in the Lead? Do you use the '_DoNotUse' append on the Lead?
Pankaj Vithal 13Pankaj Vithal 13
1. Nope, there is no such custom field on leads object but I will create one as soon as I'm done typing this
2. _doNotUse part we are not going to use on leads so we can delete off that part from the code

I kinda looked up and this is what i found, not sure if this is test class:

public class Utils{
    public static boolean firstRun = true;
    
    public static Map<string, Id> GetPCOwnerIdMap(set<string> setPC){
        Map<string, Id> mapRet= new Map<string, Id>();    
        for(User_Territory_Map__c um : [Select POSTAL_CODE__c, Assigned_User__c from User_Territory_Map__c Where POSTAL_CODE__c in :setPC]){
            mapRet.put(um.POSTAL_CODE__c.left(3).trim(), um.Assigned_User__c);
        }
        return mapRet;
    }

}
Ryan GreeneRyan Greene
Thanks for checking, that's not the test but is part of the trigger, so I'll mneed that any way. If you open the developer console, go to open and you'll see a screen like below. Click on the trigger nammed ContactUpdateOwner and see if there is a related Test class
User-added image
Pankaj Vithal 13Pankaj Vithal 13
This?

/**
 * Test class for class Utils
 */
@IsTest public class UtilsTest {
    @IsTest public static void testGetPCOwnerIdMap() {
               
        set<string> setPC=new set<string>();
        setPC.Add('M4X');
        User_Territory_Map__c um= new User_Territory_Map__c(POSTAL_CODE__c='M4X', Assigned_User__c=UserInfo.GetUserId());
        insert um;        
        Utils.GetPCOwnerIdMap(setPC);
                       
    }    
}
Ryan GreeneRyan Greene
Trigger:
trigger LeadUpdateOwner on Lead (before insert, before update) {
    if(Utils.firstRun || Test.isRunningTest()){
        Utils.firstRun=false;
        
        set<string> setPC= new set<string>();
        if(Trigger.isBefore && Trigger.isInsert){
            for(Lead l : Trigger.New){
                if(l.PostalCode != null && !l.Override_Owner_Rules__c){
                    setPC.Add(l.PostalCode.left(3).trim());
                }
            }
        }
        
        if(Trigger.isBefore && Trigger.isUpdate){
            for(Lead l : Trigger.New){
                // If a contacts postal code was changed and not set to override rules
                if(l.PostalCode != null && Trigger.OldMap.get(l.id).PostalCode != l.PostalCode && !l.Override_Owner_Rules__c){
                    setPC.Add(l.PostalCode.left(3).trim());
                }
            }
        }
        
        if(setPC.size()>0){
            List<Lead> lstLd= new List<Lead>();
            Map<string, Id> mapPCOwnerId = Utils.GetPCOwnerIdMap(setPC);
            if(Trigger.isBefore && Trigger.isInsert){
                for(Lead l : Trigger.New){
                    if(l.PostalCode != null && !l.Override_Owner_Rules__c){
                        if(mapPCOwnerId.containsKey(l.PostalCode.left(3).trim())){
                            l.OwnerId=mapPCOwnerId.get(l.PostalCode.left(3).trim());
                            lstLd.Add(l);
                        }
                    }
                }
            }
            
            if(Trigger.isBefore && Trigger.isUpdate){
                for(Lead l : Trigger.New){
                    if(l.PostalCode != null && Trigger.OldMap.get(l.id).PostalCode != l.PostalCode && !l.Override_Owner_Rules__c){
                        if(mapPCOwnerId.containsKey(l.PostalCode.left(3).trim())){
                            l.OwnerId=mapPCOwnerId.get(l.PostalCode.left(3).trim());                       
                            lstLd.Add(l);
                        }
                    }
                }
            }
        }
    }
}
Utils class will stay the same.
The test you found is for the Utils class, no need to update it
See if there is another test for the ContactUpdateOwner

Let me know if you need help implementing the code!
Pankaj Vithal 13Pankaj Vithal 13
I've created this Apex trigger in sandbox developer console. Now the next step would be to create a change set include LeadUpdateOwner Apex trigger in that change set, export it to production. is that right? Will it not give me test class and code coverage errors this time?
Pankaj Vithal 13Pankaj Vithal 13
The code is totally working 100% fine in sandbox. need your last bit of help to resolve the issues whenever i move a code to productionUser-added image
Pankaj Vithal 13Pankaj Vithal 13
Still need your help in completing the last leg here because if i cannot deploy it, its no use. I found this test class

@isTest(SeeAllData=true)
public class ContactUpdateOwnerTest{
   
    static testMethod void testContactUpdateOwner() {
       set<string> setPC=new set<string>();
       setPC.Add('M4X');
       User_Territory_Map__c um= new User_Territory_Map__c(POSTAL_CODE__c='M4X', Assigned_User__c=UserInfo.GetUserId());
       insert um;
        Account[] acc = new Account[] {            
            new Account(Name = 'Test Account1')
        };
        insert acc;
        
        Contact[] con = new Contact[] {            
            new Contact(LastName = 'Test contact1_DoNotUse',AccountId = acc[0].Id, Status__c='Inactive',
            MailingStreet='100 King St W', MailingCity='Toronto', MailingState='ON', MailingPostalCode='M4X 1A1', MailingCountry='Canada'),
             new Contact(LastName = 'Test contact1_DoNotUse',AccountId = acc[0].Id, Status__c='Active',
            MailingStreet='100 King St W', MailingCity='Toronto', MailingState='ON', MailingPostalCode='M4X 1A1', MailingCountry='Canada')
        };
        
        insert con;        
        con[0].Status__c='Active'; con[0].MailingPostalCode='M4X 1A3';
        con[1].MailingPostalCode='M4X 1A2'; con[1].Status__c='Inactive';
        update con;
        
        
        //List<Contact> lstC=new List<([Select Id, Status__c,MailingPostalCode from Contact])>;
        //lstC[0].Status__c='Active';
        //lstC[1].MailingPostalCode='M4X 1A2'; lstC[1].Status__c='Inactive';
        
    }
}
Ryan GreeneRyan Greene
Pankaj,
Whn deploying code to Production you'll need to include the specific tests written for the code. The test you just posted above will be altered to complete the test. I'll post it when updated and give you some help deploying.
Thanks,
Ryan
Ryan GreeneRyan Greene
I updated your test below. Create a new class in your sandbox with the name LeadUpdateOwnerTest and paste in the code. As long as there's no problems click run test on this one and also on the test class for Utils. Make sure they both complete and have at least 75% converage. Then create an outbound change set with all 4 codes in it, the Trigger, Utils Class, and the test for both. When you deploy click run specified tests and run the two that are in the change set. Let me know if you need more help deploying! Good luck!

Updated Test:
@isTest(SeeAllData=true)
public class LeadUpdateOwnerTest{
    
    static testMethod void testLeadUpdateOwner() {
        set<string> setPC=new set<string>();
        setPC.Add('M4X');
        User_Territory_Map__c um= new User_Territory_Map__c(POSTAL_CODE__c='M4X', Assigned_User__c=UserInfo.GetUserId());
        insert um;
        
        Lead[] ld = new Lead[] {            
            new Lead(LastName = 'Test Lead1',Street='100 King St W',City='Toronto',State='ON',PostalCode='M4X 1A1',Country='Canada'),
                new Lead(LastName = 'Test Lead2',Street='100 King St W',City='Toronto',State='ON',PostalCode='M4X 1A1',Country='Canada')};
                    
                    insert ld;        
        ld[0].PostalCode='M4X 1A3';
        ld[1].PostalCode='M4X 1A2';
        update ld;       
    }
}

 
This was selected as the best answer
Pankaj Vithal 13Pankaj Vithal 13
Ryan,

Thanks!! I followed your instructions and was able to deploy the code in prod and IT IS WORKING!! my last question to you is: my boss doesn't want me to activate it yet but after a week. so where can I find the de-activate switch? 

P.S. I just deployed my first code. HAPPY!!! :)
Ryan GreeneRyan Greene
Fantastic! It's easy!
To deactivate you'll basically need to delete it from production. Easiest way is locate the trigger in the sandbox, deactivate it there, then deploy the code to production. It's been a while since I deactivated apex so I don't remember if you need to deploy the test with it. You could try it both ways and see what happens.
Happy developing!