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
tschatztschatz 

Getting a Product ID from an Opportunity

What path should I take to get a Product ID from an Opportunity? I've looked at the API and it seems to state that the PriceBookLineItem should contain the Product ID.
 
I have tried this:
 
Code:
public class CP_OpportunityClosedWon {
 public static void CP_createNewCPUser(Opportunity[] opps){
  for (Opportunity o:opps){
   if (o.StageName == 'Closed Won') {
    
    ID cID = [select contactid from opportunitycontactrole where role = 'Ship To' AND opportunityid = :o.id].contactId;
    Contact c = [select id from contact where id = :cID];
    OpportunityLineItem oli = [select id from opportunitylineitem where opportunityid = :o.Id limit 1];
    ID pbeID = oli.priceBookEntryId;
    ID pID = [Select Product2Id From PricebookEntry where id = :pbeID].product2Id;
    Product2 p = [select id from product2 where id = :pID];
    String cName = [select title from contact where id = :cID].title;
    if(p.downloadable__c == true){
     c.Portal_User__c = True;
     c.tempName__c = cName;
     update c;
    }
    String t = pbeID;
    o.tempName__c = t;
   }
  }
 }
}

 
And get this error:
 
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger CP_AddCPUser caused an unexpected exception, contact your administrator: CP_AddCPUser: execution of BeforeUpdate caused by: System.QueryException: List has no rows for assignment to SObject: Class.CP_OpportunityClosedWon.CP_createNewCPUser: line 10, column 26
 
Any help is appriciated.
 
Thanks.
 
_t
DevAngelDevAngel
Hi tschatz,

Man, that error message doesn't reference anything that I see in your code snippet.  Check any triggers you might have on your contact table.  Maybe deactivate it and try your code again and see if the error goes away.

????

:smileyindifferent:
tschatztschatz
Sorry I should have explained in better detail.
 
I have a trigger on the Opportunity object that fires everytime an Opportunity is created or updated.
 
Code:
trigger CP_AddCPUser on Opportunity (before insert, before update) {
 Opportunity[] opps = Trigger.new;
 CP_OpportunityClosedWon.CP_createNewCPUser(opps);
}

 
The trigger works and then calls the class. I had a simpler version of the class like this
 
Code:
public class CP_OpportunityClosedWon {
 public static void CP_createNewCPUser(Opportunity[] opps){
  for (Opportunity o:opps){
   if (o.StageName == 'Closed Won') {
    
    ID cID = [select contactid from opportunitycontactrole where role = 'Ship To' AND opportunityid = :o.id].contactId;
    Contact c = [select id from contact where id = :cID];
    //OpportunityLineItem oli = [select id from opportunitylineitem where opportunityid = :o.Id limit 1];
    //ID pbeID = oli.priceBookEntryId;
    //ID pID = [Select Product2Id From PricebookEntry where id = :pbeID].product2Id;
    //Product2 p = [select id from product2 where id = :pID];
    String cName = [select title from contact where id = :cID].title;
    //if(p.downloadable__c == true){
     c.Portal_User__c = True;
     c.tempName__c = cName;
     update c;
    //}
    //String t = pbeID;
    o.tempName__c = cName;
   }
  }
 }
}

 
That works and updates the tempName field in the Opportunity and the Contact. It also marks the Portal_User field as True.
 
The issue seems to be that the OpportunityLineItem(s) associated with this Opportunity don't have any priceBookEntryId(s) associated with them. So line 10 is casuing that error because pbeID = null. However the Opportunity has a product associated with it. So the base of the question is, how do I find the product that's associated with an Opportunity?
 
Thank you for your help.
 
 _t

Message Edited by tschatz on 11-13-2007 10:30 AM

tschatztschatz

Got it working! Here's the code I used, although I'm sure it could have been achieved in a more elegant manor.

Code:

public class CP_OpportunityClosedWon {
 public static void CP_createNewCPUser(Opportunity[] opps){  
  for (Opportunity o:opps){
   if (o.Order_Status__c == 'Shipped' || o.Order_Status__c == 'Definite') {
    
    ID cID = [select contactid from opportunitycontactrole where role = 'Ship To' AND opportunityid = :o.id].contactId;
    Contact c = [select id from contact where id = :cID];
    String cName = [select title from contact where id = :cID].title;
    
    OpportunityLineItem[] oli = [select id from opportunitylineitem where opportunityid = :o.Id];
    
    for (OpportunityLineItem li : oli){
     ID pID = [Select o.PricebookEntryId, o.PricebookEntry.Product2Id from OpportunityLineItem o where id = :li.id].PriceBookEntry.Product2Id;
     if(pID != null){
      Product2 p = [select id from product2 where id = :pID];
      String s = [select name from product2 where id = :pID].name;
      Boolean pd = [select downloadable__c from product2 where id = :pID].Downloadable__c;
      if(s !=null){
       o.tempName__c = s;
      }
      if(pd == true){
       c.Portal_User__c = True;
       c.tempName__c = cName;
       update c;
      }
     }
    }
   }
  }
 }
}


 This line got me the Product2Id: ID pID = [Select o.PricebookEntryId, o.PricebookEntry.Product2Id from OpportunityLineItem o where id = :li.id].PriceBookEntry.Product2Id;

_t