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
SolidLucasSolidLucas 

Case Trigger help

Hello,

I'm trying to create a trigger that updates my campaign members status after a lead or a contact fills a web to case form, my web to case is working fine is getting the id through a javascript,but  my trigger isn't working. Someone could help me?

Here is my code:
trigger bi_WebToCaseLead on Case (before insert) {
Set<String> setCampaignMail = new Set<String>();


//List<CampaignMember> listCm = [SELECT Id,Lead.Email,LeadId,ContactId,Contact.Name,Contact.Email,CampaignId FROM CampaignMember WHERE Campaign.IsActive = true];
List<CampaignMember> listAg = [SELECT Id,Lead.Email,LeadId,ContactId,Contact.Name,Contact.Email,CampaignId FROM CampaignMember WHERE Campaign.IsActive = true AND (Lead.Email  IN :setCampaignMail OR Contact.Email IN :setCampaignMail)];

    for(CampaignMember cm : listAg){
      for(Case caso : Trigger.new){
        if(!setCampaignMail.contains(caso.SuppliedEmail)){
          setCampaignMail.add(caso.SuppliedEmail);
        }
       
        if(caso.ChaveCampanha__c != null && cm.CampaignId.equals(caso.ChaveCampanha__c)){
          cm.Status = 'Respondido';
          caso.RelacionamentoLead__c = cm.LeadId;
          }
        }
      }
  update listAg;
}

 
Best Answer chosen by SolidLucas
Beau Gordon 14Beau Gordon 14
trigger bi_WebToCaseLead on Case (before insert) {
Set<String> setCampaignMail = new Set<String>();

for(Case caso : Trigger.new){
        if(!setCampaignMail.contains(caso.SuppliedEmail) && caso.SuppliedEmail != null){
          setCampaignMail.add(caso.SuppliedEmail);
        }

List<CampaignMember> listAg = [SELECT LeadId, Lead.Email, Contact.Email FROM CampaignMember WHERE Campaign.IsActive = true AND (Lead.Email  IN :setCampaignMail OR Contact.Email IN :setCampaignMail)];

Map<string,Id> emailToCM = new Map<string,CampaignMember>();


for(CampaignMember cm : listAg){

//I am assuming that Lead.Email takes precedence over Contact.Email if a CampaignMember has both, but I don't know what you want here
string email;
if(cm.Lead.Email != null)
{
email = cm.Lead.Email;
}
else if(cm.Contact.Email != null)
{
email = cm.Contact.Email;
}

if(!(emailToCM.ContainsKey(email)) && email != null)
{
emailToCM.Add(email,cm);
}
}

List<CampaignMember> campaignMembersToUpdate = new List<CampaignMember>();

for(Case caso: Trigger.new)
{
CampaignMember cm =  emailToCM.Get(case.SuppliedEmail);    
       
if(caso.ChaveCampanha__c != null && cm.CampaignId.equals(caso.ChaveCampanha__c))
{
cm.Status = 'Respondido';
campaignMembersToUpdate.Add(cm);

caso.RelacionamentoLead__c = cm.LeadId;
}
}
}
}
I wrote this in notepad so there might be some syntax error somewhere.  Get the set of SuppliedEmail(s) by iterating through all the cases.  Use that set to query for the campaign members.  Map the SuppliedEmail values to the CampaignMembers and store that in a Map.  Then iterate through the cases again and look up the associated CampaignMember in the map.

One caution is this - you aren't going to be able to add the CaseId to the CampaignMember.  I don't know if you were planning to, but the case Id values will be null since this is a before trigger.  If you need to update CampaignMember with the Id of the case then you need to change your approach so that update happens in an after trigger.

All Answers

Beau Gordon 14Beau Gordon 14
setCampaignMail is empty when you run your query.  Your query then returns no results so listAg is empty.

Can you provide a little more detail about what you want it to do?

I think you will want to start by iterating through Trigger.new to get a set of the SuppliedEmail values first, then query for the related CampaignMember records.
SolidLucasSolidLucas
Hello Beau!

How are you?

What i want to do is basically that my trigger updates the status of my campaing member to "answered" after the user fills my web to case form,so this update basically will happen when the case is created through this web to case. 

Regards
Lucas
Beau Gordon 14Beau Gordon 14
trigger bi_WebToCaseLead on Case (before insert) {
Set<String> setCampaignMail = new Set<String>();

for(Case caso : Trigger.new){
        if(!setCampaignMail.contains(caso.SuppliedEmail) && caso.SuppliedEmail != null){
          setCampaignMail.add(caso.SuppliedEmail);
        }

List<CampaignMember> listAg = [SELECT LeadId, Lead.Email, Contact.Email FROM CampaignMember WHERE Campaign.IsActive = true AND (Lead.Email  IN :setCampaignMail OR Contact.Email IN :setCampaignMail)];

Map<string,Id> emailToCM = new Map<string,CampaignMember>();


for(CampaignMember cm : listAg){

//I am assuming that Lead.Email takes precedence over Contact.Email if a CampaignMember has both, but I don't know what you want here
string email;
if(cm.Lead.Email != null)
{
email = cm.Lead.Email;
}
else if(cm.Contact.Email != null)
{
email = cm.Contact.Email;
}

if(!(emailToCM.ContainsKey(email)) && email != null)
{
emailToCM.Add(email,cm);
}
}

List<CampaignMember> campaignMembersToUpdate = new List<CampaignMember>();

for(Case caso: Trigger.new)
{
CampaignMember cm =  emailToCM.Get(case.SuppliedEmail);    
       
if(caso.ChaveCampanha__c != null && cm.CampaignId.equals(caso.ChaveCampanha__c))
{
cm.Status = 'Respondido';
campaignMembersToUpdate.Add(cm);

caso.RelacionamentoLead__c = cm.LeadId;
}
}
}
}
I wrote this in notepad so there might be some syntax error somewhere.  Get the set of SuppliedEmail(s) by iterating through all the cases.  Use that set to query for the campaign members.  Map the SuppliedEmail values to the CampaignMembers and store that in a Map.  Then iterate through the cases again and look up the associated CampaignMember in the map.

One caution is this - you aren't going to be able to add the CaseId to the CampaignMember.  I don't know if you were planning to, but the case Id values will be null since this is a before trigger.  If you need to update CampaignMember with the Id of the case then you need to change your approach so that update happens in an after trigger.
This was selected as the best answer
SolidLucasSolidLucas
Hey,Beau!

I've tooked a little bit of your logic and applied into my code and guess what? it worked! thank you for your suport!
 
trigger bi_WebToCaseLead on Case (before insert) {

Set<String> setCampaignMail = new Set<String>();

      for(Case caso : Trigger.new){
        if(!setCampaignMail.contains(caso.SuppliedEmail) && caso.SuppliedEmail != null){
          setCampaignMail.add(caso.SuppliedEmail);
        }
        List<CampaignMember> listCm = [SELECT Id,Lead.Email,LeadId,ContactId,Contact.Name,Contact.Email,CampaignId FROM CampaignMember WHERE Campaign.IsActive = true AND (Lead.Email  IN :setCampaignMail OR Contact.Email IN :setCampaignMail)];
        Map<String, CampaignMember> mapCm = new Map<String, CampaignMember>();

      for(CampaignMember cm : listCm){
        mapCm.put(cm.Contact.Email, cm);
        mapCm.put(cm.Lead.Email, cm);
        Case tempCase = caso;
        CampaignMember tempCampaign = mapCm.get(caso.SuppliedEmail);
        if(tempCampaign != null && tempCampaign.CampaignId.equals(caso.ChaveCampanha__c)){
          tempCampaign.Status = 'Respondido';
          caso.RelacionamentoLead__c = tempCampaign.LeadId;
          caso.ContactId = tempCampaign.ContactId;
        update tempCampaign;        
      }
    }
  }
}