You need to sign in to do that
Don't have an account?
Travis Wright
System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: OpportunityLineItem.OpportunityId
I am not sure how to fix this, Any help would be great.
trigger Projectrollup on Opportunity (after insert, after update)
{
Map<Id,Opportunity> oppIds = new Map<Id,Opportunity>();
List<Opportunity> updateList = new List<Opportunity>();
for(Opportunity o : Trigger.new)
{
oppIds.put(o.id,o);
}
OpportunityLineItem[] OLI = [Select UnitPrice, Quantity, PricebookEntry.Product2Id, TotalPrice,PricebookEntry.Product2.Name, Description,
Converted_to_Asset__c,Asset__c,PricebookEntry.Product2.Create_Asset__c, PricebookEntry.Product2.Sales_Order_Group__c
From OpportunityLineItem
where OpportunityId IN : oppIds.keySet()
And (PricebookEntry.Product2.Product_Reporting_Category__c = 'Services'
or PricebookEntry.Product2.Name LIKE '%Communications%')];
for(OpportunityLineItem o : OLI)
{
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'Hotline Services' || o.PricebookEntry.Product2.Sales_Order_Group__c == 'Policy Management Services' || o.PricebookEntry.Product2.Sales_Order_Group__c == 'Incident Management Services')
{
Opportunity opp = new Opportunity(id= o.OpportunityId);
opp.Implementation_Team__c = true;
updateList.add(opp);
}
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'ReadyTraining Services')
{
Opportunity opp = new Opportunity(id=o.OpportunityId);
opp.Training_Team__c = true;
updateList.add(opp);
}
}
if(updateList.size()>0)
{
update updateList;
}
}
trigger Projectrollup on Opportunity (after insert, after update)
{
Map<Id,Opportunity> oppIds = new Map<Id,Opportunity>();
List<Opportunity> updateList = new List<Opportunity>();
for(Opportunity o : Trigger.new)
{
oppIds.put(o.id,o);
}
OpportunityLineItem[] OLI = [Select UnitPrice, Quantity, PricebookEntry.Product2Id, TotalPrice,PricebookEntry.Product2.Name, Description,
Converted_to_Asset__c,Asset__c,PricebookEntry.Product2.Create_Asset__c, PricebookEntry.Product2.Sales_Order_Group__c
From OpportunityLineItem
where OpportunityId IN : oppIds.keySet()
And (PricebookEntry.Product2.Product_Reporting_Category__c = 'Services'
or PricebookEntry.Product2.Name LIKE '%Communications%')];
for(OpportunityLineItem o : OLI)
{
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'Hotline Services' || o.PricebookEntry.Product2.Sales_Order_Group__c == 'Policy Management Services' || o.PricebookEntry.Product2.Sales_Order_Group__c == 'Incident Management Services')
{
Opportunity opp = new Opportunity(id= o.OpportunityId);
opp.Implementation_Team__c = true;
updateList.add(opp);
}
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'ReadyTraining Services')
{
Opportunity opp = new Opportunity(id=o.OpportunityId);
opp.Training_Team__c = true;
updateList.add(opp);
}
}
if(updateList.size()>0)
{
update updateList;
}
}
You can add OpportunityId in query while query..you have not queried this fields and you are using so ypu are getting this error..
Thanks,
Sandeep
You can simply replace your query with below query
Please check and let me know if it helps..To avoid these kind of error you should always query all the fields which we are using or reffering in code ....
Thanks,
Sandeep
As Sandeep already has mentioned, you have to query the field OpportunityId to fix the error. Apart from that you have the move the update operation to a future operation. As you are trying to update the same records in an after trigger, the records will be locked for update in a synchronous operation. Use the following code,
Trigger,
Future handler class,
First create the class OpportunityTriggerHandler and then modify the trigger.
--Akram
I have a couple questions as I have followed the suggestions but I am not seeing the update happen. Following the record I see if pass through the trigger and add the record to the list but I am not sure if the Class is firing as I don't see any update. Any way to determine if this is happening?
Also on a side note this is just the base and I have to expand it to include a couple different product lines. One being any product that Contains Communication within the name. I have done some research and just can't grasp the Contains formula within APEX. Can you please provide an example of this?
Thanks
Travis
Sure we are getting ready to start transferring closed won opportunities to our implementations team that uses a different system. The problem is that an opporutunity needs to create multiple projects based of the implementation service that are selected. In the code you see the IF statements that help me identify which devision in implementations needs a project created. The code only reflexs 2 of the 4 teams. Implementations which handles the following,
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'Hotline Services' || o.PricebookEntry.Product2.Sales_Order_Group__c == 'Policy Management Services' || o.PricebookEntry.Product2.Sales_Order_Group__c =='Incident Management Services')
Training which handles the following,
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'ReadyTraining Services')
Communications which should be,
if(o.PricebookEntry.Product2.Name Contains "Communications"
Than professional services which is going to be handled by
if(o.PricebookEntry.Product2.Sales_Order_Group__c == 'Professional Services')
I am not sure how to handle the Contains Statement within the Communication If Statement.
Also I am not sure if I am putting the
if(!System.isFuture()){} in the right spot can you show me?
We need this if statement to avoid infinite stack of recursive call. Our update statement in the future handler will invoke the trigger again, so we have to make sure the trigger does not calls the future method for the second time.
If I understood your other requirement correctly you need to put two more if blocks inside the for loop on OLI. And you need help with the third if block. This is how we check contains in Apex,
Please note that this checks in case sensitive manner, i.e. 'communications' and 'Communications' are different. If you want case insensitive check use this, Let me know if this solves your requirement.
--Akram
OK So after testing this I am getting a duplicateId in list error. I think this is because there are 3 different products that fall in the first list for implmentations. Is there a limit function that I can use to limit it to 1, So if it finds 1 product that matchs it just adds the ID and moves on to the next List?
Or do I have to write and limit Queries? I would prefer not to write multiple Queries due to limits.
You have to make use of Set and Map. I have modified the code,
Trigger,
Apex Class,
--Akram
Thanks for all the help. I have never used an @Future class so it something nice to know. I have noticed that this doesn't update if they remove the product that has caused the update. IE, If they were going to sell training but then updated the OLI by removing the Training Product it doesn't update the Checkbox to false.
Would it be best to add this to the Future task by writing it as an Else Statement or would it be best to make these fields Null in the trigger and let the class update them. I am afraid that if I put it in the trigger I might cause some issues down the road but in the future task I am not sure how to add it as I don't understand the If Statement that you have writen. I guess this is due to the lack of APEX knowledge that I have.
The Sales Reps would be deleting the OLI.
--Akram
Thanks I will give it a try and let you know, Thanks again for all the help.