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
Valerio_81Valerio_81 

Apex Trigger On Opportunity Products - copy Products code(s) to the Opportunity

Hi,

 

I'm not a developer but I need an help for a Trigger that I tried to do.

 

I need to store all the product code(s) linked to an opportunity after insert/delete/update/undelete of a Product.

 

I've created a field in the Opportunity table (Product_Code_Selected__C) in order to store this information.

 

I'm able to get the PricebookEntryID but I need to store the product code. I Know that I have to do a sub query, but I tried without success. 

I have also an issue if I try to delete a product from an opportunity (I'm expecting that the field will be updated without the product deleted) but I'm receiving this error message:

 

OppProductCode_trigger: execution of AfterDelete

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

Trigger.OppProductCode_trigger: line 5, column 1

 

Could you please help me? This is the Aper Trigger

 

trigger OppProductCode_trigger on OpportunityLineItem (after delete, after insert, after undelete, 
after update) {
    //Setup the array to hold the Id to Iterate through
    Set<Id> CurrentOppId = new Set<Id>();
        for (OpportunityLineItem OppLnItem : Trigger.new){
        	CurrentOppId.add(OppLnItem.OpportunityId);
    }
 
    	// Create List of One Opportunity Id to Update
	    List<Opportunity> OppId = 
	    	[Select o.Id from Opportunity o
	    		where o.Id in: CurrentOppId];

    		// Create List of Opportunity Products to iterate through later
		    List<OpportunityLineItem> relatedOLIs =
			    [Select oli.Id, oli.PricebookEntryId from OpportunityLineItem oli
	    			where oli.OpportunityId in: CurrentOppId];

    // Used to not add ',' on first OpportunityLineItem PricebookEntryID
    Boolean isFirst = true;
       
    //Iterate through the Opportunity to Update (should be just one record)
    for (Opportunity opp2 : OppId){
	    opp2.Product_Code_Selected__c = '';

	    //Iterate through the line items to add PricebookEntryID data to the Opportunity
	    for (OpportunityLineItem oli2 : relatedOLIs){
	                   	if(isFirst) {
	                		opp2.Product_Code_Selected__c += oli2.PricebookEntryId;
	                		isFirst = false;
	            		}
	            		else {
	                		opp2.Product_Code_Selected__c += ',' + oli2.PricebookEntryId; 
		            	}
	    }
    }
	try{
        update OppId;
    }catch(DMLException d){
        system.debug('\n\nERROR UPDATING Opportunity: '+d.getDMLMessage(0));
    }
}

 Many thanks in advance

Regards

Valerio

 

Best Answer chosen by Admin (Salesforce Developers) 
magicforce9magicforce9

You can do it with his query..

List<OpportunityLineItem> relatedOLIs =
[Select oli.Id, oli.PricebookEntry.Product2.ProductCode from OpportunityLineItem oli where oli.OpportunityId in: CurrentOppId];

 and every time you want to access it, use the same relationship name

for(OpportunityLineItem item : relatedOLIs){
<some variable/field> = item.PricebookEntry.Product2.ProductCode;

 

 

All Answers

magicforce9magicforce9

Hi,

 

You can't access Trigger.new values in AfterDelete Context, hence that error..You need to use Trigger.Old values

 

If you want to run the trigger in all  4 contexts (insert/delete/update/undelete) then use an if condition in your trigger...for example see the code below.

 

trigger OppProductCode_trigger on OpportunityLineItem (after delete, after insert, after undelete, 
after update) {
    //Setup the array to hold the Id to Iterate through
    Set<Id> CurrentOppId = new Set<Id>();
    //Use this if Condition to check if the trigger is running in Delete context
    If(trigger.isDelete)
    {
		for (OpportunityLineItem OppLnItem : Trigger.old){
        	CurrentOppId.add(OppLnItem.OpportunityId);
    	}
    }
    else {
        for (OpportunityLineItem OppLnItem : Trigger.new){
        	CurrentOppId.add(OppLnItem.OpportunityId);
    	}
    }

//Continue with your rest of the code.....

 

Valerio_81Valerio_81

Hi,

 

thank you very much for the help, it solved the error message!

 

Do you also know how to modify the query in order to store the product code instead the PricebookEntryID?

I tried to do some sub-queries, but these are not working.

The relationship should be 

       OpportunityLineItem.PricebookEntryId -> PricebookEntry.Id

       PricebookEntry.Product2Id -> Product2.Id
I need the field Product2.ProductCode.

 

Many thanks

Regards

Valerio

magicforce9magicforce9

You can do it with his query..

List<OpportunityLineItem> relatedOLIs =
[Select oli.Id, oli.PricebookEntry.Product2.ProductCode from OpportunityLineItem oli where oli.OpportunityId in: CurrentOppId];

 and every time you want to access it, use the same relationship name

for(OpportunityLineItem item : relatedOLIs){
<some variable/field> = item.PricebookEntry.Product2.ProductCode;

 

 

This was selected as the best answer
Valerio_81Valerio_81

Hi,

 

that's perfect!

Many thanks again for your help, really apreciated!

 

Regards

Valerio