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
Matt FieldMatt Field 

Help with a simple trigger

I am looking for some help with a simple trigger.  I want to update the opportunity with the product name from the product2 object.  I can't get it to work for some reason.

 

trigger addServiceInformation on Opportunity (before insert, before update) {

	Set<Id>oppIds = new Set<Id>();
	Map<Id,String>oppIdMap = new Map<Id,String>();
	
	for(Integer i = 0;i<Trigger.new.size();i++){
		
		oppIds.add(Trigger.new[i].Id);
		
		
	}
	for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name FROM OpportunityLineItem WHERE Id IN:oppIds AND HasRevenueSchedule = TRUE]){
		oppIdMap.put(oli.Id, oli.PricebookEntry.Product2.Name);
		
	}
	
	for(Opportunity o: Trigger.new){
		o.Service_Name__c=oppIdMap.get(o.Id);
	}
}

 Eventually, I would like to add more than 1 field with the same trigger, but the second field is a picklist, and I don't know how to add a picklist value to a text field in a trigger.

 

Any help will be GREATLY appreciated.

Best Answer chosen by Admin (Salesforce Developers) 
souvik9086souvik9086

Change like this

 

trigger addServiceInformation on Opportunity (before insert, before update) {

Set<Id>oppIds = new Set<Id>();
Map<Id,String>oppIdMap = new Map<Id,String>();

for(Integer i = 0;i<Trigger.new.size();i++){

oppIds.add(Trigger.new[i].Id);


}
for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name,OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
oppIdMap.put(oli.OpportunityId, oli.PricebookEntry.Product2.Name);

}

for(Opportunity o: Trigger.new){
o.Service_Name__c=oppIdMap.get(o.Id);
}
}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

All Answers

Eli Flores, SFDC DevEli Flores, SFDC Dev

You are using the map incorrectly. 

 

In the 

oppIdMap.put

you are mapping to the ID of the opportunityLineItem but you are trying to get using the OpportunityID.

 

You have the same problem in the SOQL queery you are looking for OpportunityLineItems with ID that are in a set of Opportunity IDs.

 

You proably just need to switch to this

for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name, OpportunityID FROM OpportunityLineItem WHERE OpporunityID IN:oppIds AND HasRevenueSchedule = TRUE]){
		oppIdMap.put(oli.OpportunityId, oli.PricebookEntry.Product2.Name);

There's still the issue of if an opportunity has more than 1 product line item, it's only going to pick up the name of one product.

 

Also for the picklist. It operates like a text field for all intents and purposes. If you need a strict adherence to the underlying picklist values.. You can do this using a describe call. Here's some information about Retrieve picklist values in apex

souvik9086souvik9086

Change like this

 

trigger addServiceInformation on Opportunity (before insert, before update) {

Set<Id>oppIds = new Set<Id>();
Map<Id,String>oppIdMap = new Map<Id,String>();

for(Integer i = 0;i<Trigger.new.size();i++){

oppIds.add(Trigger.new[i].Id);


}
for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name,OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
oppIdMap.put(oli.OpportunityId, oli.PricebookEntry.Product2.Name);

}

for(Opportunity o: Trigger.new){
o.Service_Name__c=oppIdMap.get(o.Id);
}
}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

This was selected as the best answer
Matt FieldMatt Field

Thank you both for your help. 2 questions souvik9086.

 

1.  If I want to update multiple fields, can I use just the one trigger, or do I have to create another trigger?

2.  If I want to have the field(s) populated whenever there is a product associated with the opportunity rather than on new opportunities, how would I change the "Trigger.New" statements?

 

Thanks again!!

souvik9086souvik9086

Hi,

 

1.  If I want to update multiple fields, can I use just the one trigger, or do I have to create another trigger?

Ans - You can update those in the same trigger like the following. No need to create another trigger.

You have to keep in the map value whole OpportunityLineItem object.

 

2.  If I want to have the field(s) populated whenever there is a product associated with the opportunity rather than on new opportunities, how would I change the "Trigger.New" statements?

 

Ans - Yes obviously you can.

Check the below modified trigger answering both the questions.

 

trigger addServiceInformation on Opportunity (before insert, before update) {

Set<Id>oppIds = new Set<Id>();
Map<Id,String>oppIdMap = new Map<Id,String>();

for(Integer i = 0;i<Trigger.new.size();i++){

oppIds.add(Trigger.new[i].Id);


}
for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name,OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
oppIdMap.put(oli.OpportunityId, oli);

}

for(Opportunity o: Trigger.new){

if(oppIdMap.get(o.Id).PricebookEntry.Product2.Name != NULL){ // This the answer of your 2nd question

o.Service_Name__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Name;

o.OtherField = //Your Value; // This is the answer of your first question

}
}
}

 

If the post helps you please throw KUDOS.

Thanks

Matt FieldMatt Field

I'm getting an error that says:  "Method does not exist or incorrect signature" at this line:

 

		oppIdMap.put(oli.OpportunityId, oli.PricebookEntry.Product2.Name, oli.PricebookEntry.Product2.Family);

 Here is the whole trigger:

 

trigger addServiceInformation on Opportunity (before insert, before update) {

	Set<Id>oppIds = new Set<Id>();
	Map<Id,String>oppIdMap = new Map<Id,String>();
	
	for(Integer i = 0;i<Trigger.new.size();i++){
		oppIds.add(Trigger.new[i].Id);
	}

	for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family, OpportunityId FROM OpportunityLineItem 
	WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
		oppIdMap.put(oli.OpportunityId, oli.PricebookEntry.Product2.Name, oli.PricebookEntry.Product2.Family);
	}

	for(Opportunity o: Trigger.new){
		if(oppIdMap.get(o.Id).PricebookEntry.Product2.Name != NULL){
			
		o.Service_Name__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Name;
		o.Service_Family__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Family;
		
		}
	}

}

 Any thoughts on how I screwed this up?  :)

souvik9086souvik9086

Change it like this

 

trigger addServiceInformation on Opportunity (before insert, before update) {

Set<Id>oppIds = new Set<Id>();
Map<Id,OpportunityLineItem>oppIdMap = new Map<Id,OpportunityLineItem>();

for(Integer i = 0;i<Trigger.new.size();i++){
oppIds.add(Trigger.new[i].Id);
}

for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family, OpportunityId FROM OpportunityLineItem
WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
oppIdMap.put(oli.OpportunityId, oli);
}

for(Opportunity o: Trigger.new){
if(oppIdMap.get(o.Id).PricebookEntry.Product2.Name != NULL){

o.Service_Name__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Name;
o.Service_Family__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Family;

}
}

}

 

If the post helps you, please throw KUDOS.

Thanks

Matt FieldMatt Field

Thanks!!  I really appreciate your help with this.  Now I am getting the following error when I deploy to production:

 

System.NullPointerException:  Attempt to de-reference a null object.  Line 16 Column 1

 

Here is line 16:

 

if(oppIdMap.get(o.Id).PricebookEntry.Product2.Name != NULL){

 

Any thoughts as to why that is coming up?

 

Thanks again,

 

Matt

souvik9086souvik9086

Check it like this

trigger addServiceInformation on Opportunity (before insert, before update) {
Set<Id>oppIds = new Set<Id>();
Map<Id,OpportunityLineItem>oppIdMap = new Map<Id,OpportunityLineItem>();

for(Integer i = 0;i<Trigger.new.size();i++){
oppIds.add(Trigger.new[i].Id);
}
for(OpportunityLineItem oli:[SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family, OpportunityId FROM OpportunityLineItem
WHERE OpportunityId IN:oppIds AND HasRevenueSchedule = TRUE]){
oppIdMap.put(oli.OpportunityId, oli);
}
for(Opportunity o: Trigger.new){
if(oppIdMap.get(o.Id) != NULL){
if(oppIdMap.get(o.Id).PricebookEntry.Product2.Name != NULL){

o.Service_Name__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Name;
o.Service_Family__c = oppIdMap.get(o.Id).PricebookEntry.Product2.Family;

}
}
}
}

 

If the post helps you please throw KUDOS.

Thanks.