+ Start a Discussion
sam_Adminsam_Admin 

Help with trigger

Hi Guys,

       Iam trying to update parent campaign based on record type it's working fine when i create a new one but when iam trying to change the record type for existing campaign the parent campaign doesn't gets updated, iam kinda new to this coding, any help is appreciated, here is my trigger

 

trigger ParentCampaign on Campaign (after insert) {
String CampaignID =Trigger.new[0].Id;
Campaign Cmp=[select id, RecordTypeID,ParentID from Campaign where id =:CampaignID];
If (Cmp.RecordTypeID =='012400000004v8d'){
Cmp.ParentID='701Q0000000Cxq2';
}
else if
(Cmp.RecordTypeID =='012300000004svr'){
Cmp.ParentID='701Q0000000CxqM';
}
else if
(Cmp.RecordTypeID =='012300000004svw'){
Cmp.ParentID='701Q0000000CxqR';
}
else if
(Cmp.RecordTypeID =='012300000004sw1'){
Cmp.ParentID='701Q0000000CxqW';
}
else if
(Cmp.RecordTypeID =='01240000000M32w'){
Cmp.ParentID='701Q0000000Cxqb';
}
else if
(Cmp.RecordTypeID =='012400000004umS'){
Cmp.ParentID='701Q0000000Cxqg';
}
Update cmp;
}

 

Best Answer chosen by Admin (Salesforce Developers) 
Ritesh AswaneyRitesh Aswaney
You wouldn't need to select the records or update the, as they are already available in the trigger context. Try this

trigger ParentCampaign on Campaign (before insert, before update) {


For(Campaign Cmp : trigger.new)
{
If (Cmp.RecordTypeID =='012400000004v8d')
Cmp.ParentID='701Q0000000Cxq2';

else if (Cmp.RecordTypeID =='012300000004svr')
Cmp.ParentID='701Q0000000CxqM';

else if (Cmp.RecordTypeID =='012300000004svw')
Cmp.ParentID='701Q0000000CxqR';

else if
(Cmp.RecordTypeID =='012300000004sw1')
Cmp.ParentID='701Q0000000CxqW';

else if (Cmp.RecordTypeID =='01240000000M32w')
Cmp.ParentID='701Q0000000Cxqb';

else if (Cmp.RecordTypeID =='012400000004umS')
Cmp.ParentID='701Q0000000Cxqg';


}
}

All Answers

MarkWaddleMarkWaddle

Hi Sam,

 

Welcome to the world of SF triggers. Your trigger is only fired on insert. If you want it to fire on update as well then you need to change the first line to

 

 

trigger ParentCampaign on Campaign (after insert, after update) {

Secondly, there is not a need to query for the campaign object. It is already available in the Trigger.new list.

 

Thirdly, your trigger is only going to update the first campaign record, even if more than one campaign record is being edited at once. You need to "bulkify" your trigger.

 

 

And finally, it is never a good idea to hard-code IDs into any Salesforce code. I see you are doing that for RecordTypes and for Campaigns. The reason this is a problem is that the same record can have different IDs in different environments.

 

To access the RecordTypeID for a record type by name you can use code like this:

 

if (Cmp.RecordTypeID == Schema.SObjectType.Campaign.getRecordTypeInfosByName().get('MyRecordTypeNameHere').getRecordTypeId()) {

To get the IDs for your parent campaigns, I would recommend querying them by name and/or by RecordTypeID, whatever unique combination will give you the right campaign. For example:

Id parentRecordTypeOne = Schema.SObjectType.Campaign.getRecordTypeInfosByName().get('ParentOneRecordType').getRecordTypeId();
Id parentIdOne = [select Id from Campaign where Name='The Name of my Parent Campaign' and RecordTypeId = :parentRecordTypeOne];
// ... Get other ids ...

for (Campaign Cmp : trigger.new) {
//...
Cmp.ParentID = parentIdOne;
//...
}

 

 

Ritesh AswaneyRitesh Aswaney
On an unrelated note, you can save yourselAnanda update by using a before insert trigger. As a thumb rule, when you are looking to update fields on the object which fires the trigger, you're best using a before trigger, rather an an after trigger.
sam_Adminsam_Admin

Mark,

     i tried using after update but iam getting exception error and to be honest i didn't understand your code , you are right that i cannot use the Id's in trigger but i was trying to organize your code but couldn't do that :(

 

Ritesh: Before insert doesn't works for me , iam trying to update when i create a new one and even when i edit the record

 

thx for your suggestion guys

 

Ritesh AswaneyRitesh Aswaney
Well there is before insert and before update
So your trigger can be
Trigger CampaignBefore on Campaign (before insert, before update)

This will fire for inserts and updates
sam_Adminsam_Admin

Thx again,this is what i got when i used before insert and before update

 

Apex trigger ParentCampaign caused an unexpected exception, contact your administrator: ParentCampaign: execution of BeforeInsert caused by: System.QueryException: List has no rows for assignment to SObject: Trigger.ParentCampaign: line 3, column 14

Ritesh AswaneyRitesh Aswaney
You wouldn't need to select the records or update the, as they are already available in the trigger context. Try this

trigger ParentCampaign on Campaign (before insert, before update) {


For(Campaign Cmp : trigger.new)
{
If (Cmp.RecordTypeID =='012400000004v8d')
Cmp.ParentID='701Q0000000Cxq2';

else if (Cmp.RecordTypeID =='012300000004svr')
Cmp.ParentID='701Q0000000CxqM';

else if (Cmp.RecordTypeID =='012300000004svw')
Cmp.ParentID='701Q0000000CxqR';

else if
(Cmp.RecordTypeID =='012300000004sw1')
Cmp.ParentID='701Q0000000CxqW';

else if (Cmp.RecordTypeID =='01240000000M32w')
Cmp.ParentID='701Q0000000Cxqb';

else if (Cmp.RecordTypeID =='012400000004umS')
Cmp.ParentID='701Q0000000Cxqg';


}
}
This was selected as the best answer
sam_Adminsam_Admin

Thx Ritesh, it worked but mark was saying that we cannot use the hard code values in the trigger, but since iam new to this trigger world i just don't knw how to store the id's in variable or just like he showed , since even the code which i have ryte now works fine but is it good to deploy this to production.

Ritesh AswaneyRitesh Aswaney
Mark is right, it is not ideal to have hardcoded strings. A middle path could be to have custom settings, which let you reference parameters in code, which can b maintained via point and click,

You could google salesforce custom settings and red up on how to use them. Jeff Douglas has written a very good blog entry describing their use,
http://blog.jeffdouglas.com/2010/01/07/using-list-custom-settings-in-salesforce-com/
sam_Adminsam_Admin

Ritesh,

       Finally the trigger has been modified to avoid the Id's and iam in process of writing test class but it just gave me 60%, but not sure how to get it to 75%, here is thr trigger and class the red ones are not being covered

 

Trigger:

trigger ParentCampaign on Campaign (before insert, before update)
{
    MAP<String,Id> ParentMap = new MAP<String,Id>();
    Map<Id,RecordType> recordTypeMap = new Map<Id,Recordtype>([Select Name,Id from Recordtype where SobjectType='Campaign']);   
    Set<String> parentName = new Set<String>();    
    for(ParentCompaign__c c : ParentCompaign__c.getall().values())
    {
        parentName.add(c.Name);
    }
    
    for(Campaign c : [Select Id,Name from Campaign where name in : parentName])
    {
        ParentMap.put(c.Name,C.Id);
    }
    
    
    For(Campaign Cmp : trigger.new)
    {
        If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (AU)')
        Cmp.ParentID=ParentMap.get('International AU4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (DE)')
        Cmp.ParentID=ParentMap.get('International DE4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (ES)')
        Cmp.ParentID=ParentMap.get('International ES4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (FR)')
        Cmp.ParentID=ParentMap.get('International FR4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (JP)')
        Cmp.ParentID=ParentMap.get('International JP4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (UK)')
        Cmp.ParentID=ParentMap.get('International UK4');
     
    }
}

 

Class:

 

@isTest
private class ParentCampaignTest {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test
       MAP<String,Id> ParentMap = new MAP<String,Id>();
       Map<Id,RecordType> recordTypeMap = new Map<Id,Recordtype>([Select Name,Id from Recordtype where SobjectType='Campaign']);  
       //Set<String> parentName = new Set<String>();  
       
         
       Account acc = new Account(Name = 'test', phone = '1234567890');
       insert acc;
      
       Case c = new Case(Type = 'Transformation', Status = 'Closed', Description = 'Text', AccountId = acc.Id);
       insert c;  
      
       Campaign_Request__c cr = new Campaign_Request__c(Name = 'Testing', Program_Type__c = 'Other', CostMin__c = 90, Target_Date__c = Date.newInstance(2008,03,01),
                                                       Sectors__c = 'Anesthesia', Sector_Contact__c = 'Baldwin');
       insert cr;
      
       Campaign cmp = new Campaign(Name = 'International AU4', Campaign_Objective__c = 'Market Development', StartDate = Date.newInstance(2009,02,01),
                                  EndDate = Date.newInstance(2010,02,01));
       insert cmp;
      
       Campaign cm = new Campaign( Name = 'Test',ParentId = cmp.Id, Campaign_Objective__c = 'Market Development', StartDate = Date.newInstance(2009,03,01),
                                  EndDate = Date.newInstance(2010,03,01));
       insert cm;
      
    }
    
}

Ritesh AswaneyRitesh Aswaney
Nice work with the record type ids Sam!

Since you have several if blocka, To increase test coverage you will need to create campaigns of the various record types in your test class.

Inserting campaigns of the different record types which your if statements are looking for, will send the execution path through the if statements.

So just create campaigns of different record types, insert them and you should be sorted
sam_Adminsam_Admin

Thx Ritesh, i modified the class infact i just copied the same code from trigger, but ryte now my test class fails, i get this msg, iam not sure how to correct it

System.NullPointerException: Attempt to de-reference a null object

Class.ParentCampaignTest.myUnitTest: line 46, column 49 External entry point

 

@isTest
private class ParentCampaignTest {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test
       MAP<String,Id> ParentMap = new MAP<String,Id>();
       Map<Id,RecordType> recordTypeMap = new Map<Id,Recordtype>([Select Name,Id from Recordtype where SobjectType='Campaign']);  
       //Set<String> parentName = new Set<String>();  
       
         
       Account acc = new Account(Name = 'test', phone = '1234567890');
       insert acc;
      
       Case c = new Case(Type = 'Transformation', Status = 'Closed', Description = 'Text', AccountId = acc.Id);
       insert c;  
      
       Campaign_Request__c cr = new Campaign_Request__c(Name = 'Testing', Program_Type__c = 'Other', CostMin__c = 90, Target_Date__c = Date.newInstance(2008,03,01),
                                                       Sectors__c = 'Anesthesia', Sector_Contact__c = 'Baldwin');
       insert cr;
      
       Campaign Cmp = new Campaign(Name = 'Testing', Campaign_Objective__c = 'Market Development', StartDate = Date.newInstance(2009,02,01),
                                  EndDate = Date.newInstance(2010,02,01));
       insert Cmp;
       
        If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (AU)')
        Cmp.ParentID=ParentMap.get('International AU4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (DE)')
        Cmp.ParentID=ParentMap.get('International DE4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (ES)')
        Cmp.ParentID=ParentMap.get('International ES4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (FR)')
        Cmp.ParentID=ParentMap.get('International FR4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (JP)')
        Cmp.ParentID=ParentMap.get('International JP4');
        else If (recordTypeMap.get(Cmp.RecordTypeID).Name == 'Campaign (UK)')
        Cmp.ParentID=ParentMap.get('International UK4');
       
       
      
    }
    
}

 

Ritesh AswaneyRitesh Aswaney

not quite, you want to be inserting campaigns of the various record types

 

Map<String, Id> nameRTIDMap = new Map<String, Id>{};

 

for(RecordType rt : recordTypemap.values)

nameRTIDMap.put(rt.name, rt.id);

 

......

 

.....

Campaign c1 = new Campaign(........, RecordTypeId = nameRTIDMap.get('Campaign (AU)')....);

insert c1;

 

Campaign c2 = new Campaign (.......RecordTypeId = nameRTIDMap.get('Campaign (DE)').....);

insert c2;

 

and so on....