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
AzeddineAzeddine 

Opportunity trigger code issue

trigger campaign_update on Opportunity (after insert,after update) {

//This trigger looks for the first contact in Account, then adds a campaignmember to the proper campaign

Opportunity[] opportunities = Trigger.new;
for (Integer i = 0; i < opportunities .size(); i++) {
Contact contact;
boolean foundContactId = false;
boolean respondedtocampaign = false;

//Verifiy that this record has a related account and a priamry campaign
if (opportunities[i].AccountId != null && opportunities[i].campaign != null) {
//Get related contactID (one and only one contact per account)
try {
contact = [SELECT Id FROM Contact WHERE AccountId = :opportunities[i].AccountId limit 1];
foundContactId = true;
} catch (Exception e){
//Found no contact on this account
}

//Check if related contact already has a a primary campaign
if (foundContactId) {
try {
Campaignmember c = [SELECT campaignID FROM campaignmember WHERE ContactID = : contact.Id AND
CampaignID = :opportunities[i].campaign limit 1];

} catch (Exception e){
//Found no primary campaign
respondedtocampaign = true;
}
}
//If reservation exists for this contact then book it
if (foundContactId && respondedtocampaign) {
// Add a new reservation to related seminar
CampaignMember cm= new CampaignMember(CampaignID = opportunities[i].Campaign,
ContactID=contact.Id,
Status='Responded');
//Insert the new reservation
insert cm;
}
}
}


}

 

 

The error is the following :

 

Error: Compile Error: Invalid bind expression type of SOBJECT:Campaign for column of type Id at line 25 column 117

 

Any idea why is this error happening ?

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox
It should be opportunities[i].CampaignID.

All Answers

sfdcfoxsfdcfox
It should be opportunities[i].CampaignID.
This was selected as the best answer
AzeddineAzeddine

Yeah, correct thank you :)

AzeddineAzeddine
Here is the thing, the code is supposed to create a campaign member but it is not doing it. Any idea why ?
sfdcfoxsfdcfox
Your code isn't well optimised, but I'll research and see if I can figure it out.
sandeep@Salesforcesandeep@Salesforce

 Agreed with marked solution and just want to add FYI that Campaign is a standard object so to get id we just simply append Id after Object name like other example 

AccountId, OpportunityId, ContactId ....etc

sfdcfoxsfdcfox
trigger campaignContact on Opportunity (after insert, after update) {
    Map<Id,Set<Id>> contactCampaigns = new Map<Id,Set<Id>>();
    CampaignMember[] members = new CampaignMember[0];
    Map<Id,Id> accountContacts = new Map<Id,Id>();
    Opportunity[] work = new Opportunity[0];
    Set<Id> campaignIds = new Set<Id>();

    for(Opportunity record:Trigger.new) {
        if(record.campaignid!=null&&record.accountid!=null) {
            campaignIds.add(record.campaignid);
            accountContacts.put(record.accountid,null);
        }
    }

    for(Account record:[SELECT Id,(SELECT Id FROM Contacts LIMIT 1) FROM Account WHERE Id IN :accountContacts.keySet()]) {
        if(!record.contacts.isempty()) {
            accountContacts.put(record.Id,record.contacts[0].Id);
        } else {
            accountContacts.remove(record.Id);
        }
    }

    for(Id contactId:accountContacts.values()) {
        contactCampaigns.put(contactId,new Set<Id>());
    }

    for(Opportunity record:Trigger.new) {
        if(accountcontacts.containskey(record.accountid) && record.campaignid != null) {
            work.add(record);
        }
    }

    for(CampaignMember record:[SELECT Id,ContactId,CampaignId FROM CampaignMember WHERE ContactId IN :accountContacts.values() AND CampaignId IN :campaignIds]) {
        contactCampaigns.get(record.contactid).add(record.campaignid);
    }

    for(Opportunity record:work) {
        if(!contactCampaigns.get(accountContacts.get(record.accountid)).contains(record.campaignid)) {
            members.add(new CampaignMember(ContactId=accountContacts.get(record.accountid),CampaignId=record.campaignId,Status='Responded'));
        }
    }
    
    insert members;
}

This is an approximate translation of your code to work correctly, even through the data loader. I tested this in my developer edition, and it appears to work. Let me know if this is what you're looking for.

AzeddineAzeddine

This is the error I am getting

 

Failure Message: "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Campaign_Update: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Attempted to add a campaign member where eithe...

sfdcfoxsfdcfox
Hmm, it's working in my developer org. I even tested it. Did you make any modifications to the code? Try adding a debug statement when adding the campaign member to the list, make sure it's getting the correct ID values.
AzeddineAzeddine
You will have to excuse me but how would I add the debug statement ?
AzeddineAzeddine

@isTest
private class campaign_updateTestclass {
    static testMethod void validateContractCloner() {
    
        Opportunity newOpportunity = new Opportunity(Name = 'testOpp',
                                                     CloseDate = System.today(),
                                                     StageName = 'Providing Information',
                                                     AccountId = '001C000000yq2Jw',
                                                     CampaignID = '701C0000000e6PF',
                                                     Presentation_Request__c='CNC Appointment',
                                                     Zip_Code__c='76021',
                                                     LeadSource='Direct Mail',
                                                     Lead_Type__C='CNC Lead'                                                    ); 
        insert newOpportunity;
        
        
    }
}

sfdcfoxsfdcfox
You shouldn't hard-code ID values like that. Instead, create an account ,insert id, then create a campaign, insert that, insert a campaign, then insert that, and finally insert the opportunity.