You need to sign in to do that
Don't have an account?
pierrefrazny.ax358
Trigger to create Campaign Member Status automatically
Is it possible to use a trigger to automate the creation of Campaign Member Status? For example, when a campaign of certain type is created, I would like to automatically add 'Show', 'No show' i nthe list of Campaign Member Status. Is it possible?
Thanks
Pierre
Yup-create an After Insert trigger on Campaign to create the statuses. Sytax is similar to this post here:
http://community.salesforce.com/sforce/board/message?message.uid=163776
I haven't checked this syntax, but something like this should work:
trigger createStatuses on Campaign (after Insert){
for (Campaign c: trigger.new){
CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=c.Id, HasResponded=true, Label='Show', SortOrder=1);
CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=c.Id, HasResponded=False, Label='No Show', SortOrder=2);
insert new List<CampaignMemberStatus>{cms1, cms2};
}
All Answers
Yup-create an After Insert trigger on Campaign to create the statuses. Sytax is similar to this post here:
http://community.salesforce.com/sforce/board/message?message.uid=163776
I haven't checked this syntax, but something like this should work:
trigger createStatuses on Campaign (after Insert){
for (Campaign c: trigger.new){
CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=c.Id, HasResponded=true, Label='Show', SortOrder=1);
CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=c.Id, HasResponded=False, Label='No Show', SortOrder=2);
insert new List<CampaignMemberStatus>{cms1, cms2};
}
John,
This worked great! thanks.
Do you know if it is possible to change the label of the default Campaign Member Status (Sent and Responded)? What if I would like in a trigger to rename 'Responded' to 'Show' for example.
Thanks
Yes - you'd query for the existing statuses and then update the label:
Id campID='yourCampaignId'; List<CampaignMemberStatus> cms=[Select Id, Label FROM CampaignMemberStatus WHERE CampaignID=campID]; for (CampaignMemberStatus cm:cms){ if(cm.Label='Responded'){ cm.Label='Show'; } }
There's a few issues with the two code samples above. The first has a DML statement in a for loop which could cause problems with governer limits. The second will fail because 'Label' is not an updateable field on the CampaignMemberStatus record. Here a sample that will remove the two default member status values and replace them each time a campaign of a certain record type is added.
trigger CampaignCommitteeStatus on Campaign (after insert) { //change default member statuses (Sent and Responded) for select campaigns Set <Id> cmpns = new Set <Id>(); for (Campaign c: trigger.new){ if (c.RecordTypeId == '01240000000M1hh') cmpns.add(c.Id); } List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>(); List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>(); for (CampaignMemberStatus cm: [Select Id, Label, CampaignID FROM CampaignMemberStatus WHERE CampaignID IN :cmpns]){ if(cm.Label == 'Responded' ){ CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Active', HasResponded=true, IsDefault = True, SortOrder=3); System.debug(cms1); cms2Delete.add(cm); cms2Insert.add(cms1); } else if(cm.Label == 'Sent'){ CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Retired', HasResponded=false, SortOrder=4); System.debug(cms2); cms2Delete.add(cm); cms2Insert.add(cms2); } } //perform insert before delete because system requires at least one CMS for a Campaign insert cms2Insert; delete cms2Delete; }
Thanks Eric,
Indeed I could not update the label for the status 'Sent' and 'Responder'. Your code works great. The only change I made is to use a SOQL statement to get the campaign ID dynamically
RecordType rt = [Select Id, Name from RecordType where Name = 'my campaign record type name' limit 1];
Thanks a lot for your post!
Pierre
So it looks like the code below is for adding new statuses:
And this code is for changing the default Sent and Responsed statuses:
What's the best way of combining the two so that the default Sent and Responded values are changed, and other values are added?
The code above actually deletes and inserts campaignmember status using the two lists "cms2Delete" and "cms2Insert".
@LloydS
What's the best way of combining the two so that the default Sent and Responded values are changed, and other values are added?
Use following steps for your solution.
1. Fetch all existing campaign member status record.
2. if Record exists update
3. if not, find maximum number of sortorder, increment it by 1 and add new record into it.
Hello Eric,
I wrote the following trigger based on what you submitted. Thanks!
I've just run into a snag, though. Everything works great except for when I try to Clone a campaign. When I clone a Campaign I get a Duplicate_Value error, and I'm struggling to debug. So, I'm curious to know if you've run into the same problem and have a solution.
The default check box is not getting set (see the Invited new status below). Any ideas?
trigger autoCampaignMemberStatusTrigger on Campaign (after insert) {
List<Campaign> newCamps = [select Id from Campaign where Id IN :trigger.new AND ParentID = Null];
List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>();
Set<Id> camps = new Set<Id>();
List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>();
List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
for(Campaign camp : newCamps){
camps.add(camp.Id);
}
for(CampaignMemberStatus cm : [select Id, Label, CampaignId from CampaignMemberStatus where CampaignId IN :camps]) {
if(cm.Label == 'Sent' || cm.Label == 'Responded') {
cms2Delete.add(cm);
}
CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false,
Label = 'Invited', SortOrder = 3, isDefault = true);
cms2Insert.add(cms1);
CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
Label = 'Accepted', SortOrder = 4);
cms2Insert.add(cms2);
CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
Label = 'Attended', SortOrder = 5);
cms2Insert.add(cms3);
CampaignMemberStatus cms4 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
Label = 'Declined', SortOrder = 6);
cms2Insert.add(cms4);
}
insert cms2Insert;
delete cms2Delete;
}
Hey,
I just checked my trigger and found the same problem. I'm not sure why. I will let you know if find anything.
I found a fix for the Cloning issue described above. I created a custom checbox field for campaigns called Campaign Template. I also created a workflow that will uncheck the Campaign Template checkbox if the Campaign Name doesn't contain the word Template.
I also changed the first line in the trigger to be:
List<Campaign> newCamps = [select Id from Campaign where Id IN :trigger.new AND ParentID = Null AND Campaign_Template__c=false];
The trigger fires before the field update workflow rule, so the Member Status values won't be changed.
When you clone a template, change the name and make sure that Template is not in the name. The Member Status Values will be as they are in the template.
If you are cloning a non-template, simply check the Campaign Template checkbox before you hit Save. Again the Member Status Values will be as in the campaign that was cloned.
Tom
Hey Tom,
Here is a more recent version that solves the cloning issue. I think Bob_Buzzard helped me through it in a different post. To be honest I don't really understand it how it works, but it does work. Just posting it as food for thought since you already found your own solution.
aKaIINV - If you notice on the edit screen for Member Status, the Default column doesn't have checkboxes, it has option buttons. If you hover over each button they are Default1, Default2, and so on.
If you put isDefault = false for all of the new status values, you get an error on the delete step that you can't delete the default. So it is recognizing that the default is being changed but that data is not being saved.
Tom
I have contacted SF support - it got bumped to 2nd level - in 48-72 hours we should know more
Tom
Got help from SF 2nd level and got this code from them and it works properly
trigger autoCampaignMemberStatusTrigger on Campaign (after insert) {
List<Campaign> newCamps = [select Id from Campaign where Id IN :trigger.new AND ParentID = Null AND Campaign_Template__c=false];
List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>();
Set<Id> camps = new Set<Id>();
List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>();
List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
for(Campaign camp : newCamps){
camps.add(camp.Id);
}
for (CampaignMemberStatus cm: [Select Id, Label, CampaignID FROM CampaignMemberStatus WHERE CampaignID IN :camps]){
if(cm.Label == 'Responded' ){
CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Email Sent', HasResponded=false, IsDefault = True, SortOrder=3);
System.debug(cms1);
cms2Delete.add(cm);
cms2Insert.add(cms1);
} else if(cm.Label == 'Sent'){
CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Called', HasResponded=false, SortOrder=4);
System.debug(cms2);
cms2Delete.add(cm);
cms2Insert.add(cms2);
CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true, Label = 'Appointment Set', SortOrder = 5);
cms2Insert.add(cms3);
}
}
//perform insert before delete because system requires at least one CMS for a Campaign
insert cms2Insert;
delete cms2Delete;
}
To save the hassle of writting the trigger, I have written a free App. This will shortly be available on the AppExchange, but you can see details/install now from: http://www.aakonsult.com/AAKCampaignStatus.html