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
oodsigmaoodsigma 

Opportunity mass edit child object error: Id value is not valid for standard controller

Hi developer heroes,

 

I'd love to pick your brain with the following scenario.

 

Standard Object-Master: Opportunity

Custom Object-Child: Produkt_Ressourcen_Forecast__c

Visualforce Page: ProductResourceForecast

Controller Extension: extForecastProducts

 

What I try to accomplish is an "Edit all" VS page for the custom object. When I click on "Edit all" the following error pops up:

 

Error: Id value 006L0000002BRTw is not valid for the Produkt_Ressourcen_Forecast__c standard controller 

 

The interesting part is, when checking the Id mentioned above it matches the Oppty Id the custom object belongs to.

 

I skimmed the boards already but I wasn't able to get this one fixed myself. Since it is day3 of VF for me, help is much appreciated!

 

--------------------------------

 

The Controller Extension:


public class extForecastProducts{
private final Produkt_Ressourcen_Forecast__c ForecastProducts;

List<Produkt_Ressourcen_Forecast__c> lstForecastProducts;

Opportunity ForecastProductsNew;

public extForecastProducts(ApexPages.StandardController controller) {
this.ForecastProducts= (Produkt_Ressourcen_Forecast__c)controller.getRecord();


// get Oppty Id from custom object where current id matches


Id Opps= [Select OpportunityID__c FROM Produkt_Ressourcen_Forecast__c 
where Id =: ApexPages.currentPage().getParameters().get('id')].OpportunityID__c;
lstForecastProducts = (List<Produkt_Ressourcen_Forecast__c>)[ 

// get fields of custom object


Select Id,
Contact__c, 
Cost__c, Cost_Type__c, 
Forecast_Product__c,
ID__c,
Forecast_Quantity__c,
Forecast_Unit__c, 
Leistung_erbracht__c, 
Mitarbeiter_Rolle__c,
Opportunity_Line_Item_Id__c,
Opportunity_TS_BETA__c,
Product__c,
Product_Code__c,
Profitability__c,
Quantity__c,
Sales_Price__c,
SFDC_Lizenz_Preis__c,
Subunternehmen__c,
To__c,
Total_Cost__c,
Total_Margin__c,
Total_Price__c,
Unit__c, 
OpportunityID__c 

From Produkt_Ressourcen_Forecast__c
where OpportunityID__c =: Opps]; 
ForecastProductsNew = [Select Id, Name From Opportunity Where Id =: Opps];
}
public List<Produkt_Ressourcen_Forecast__c> getlstForecastProducts(){
return lstForecastProducts;
}
public Opportunity getForecastProductsNew(){
return ForecastProductsNew;
}

public PageReference save() {
update lstForecastProducts;
return (new ApexPages.StandardController(ForecastProductsNew)).view();

}

 

The VS Page:

 

<apex:page standardController="Produkt_Ressourcen_Forecast__c" tabStyle="Opportunity" sidebar="false" extensions="extForecastProducts">
<apex:form >
<apex:pageBlock >
<apex:pageMessages />

<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!Save}"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</apex:pageBlockButtons>

<apex:pageBlockTable value="{!lstForecastProducts}" var="prod" id="prod_table">
<apex:column value="{!prod.Name}"/>
<apex:column headerValue="Opportunity">
<apex:inputField value="{!prod.Opportunity_TS_BETA__c}"/>
</apex:column> 
<apex:column headerValue="Forecast Product">
<apex:inputField value="{!prod.Forecast_Product__c}"/>
</apex:column> 
<apex:column headerValue="Leistung erbracht">
<apex:inputField value="{!prod.Leistung_erbracht__c}"/>
</apex:column>
<apex:column headerValue="Mitarbeiter Rolle">
<apex:inputField value="{!prod.Mitarbeiter_Rolle__c}"/>
</apex:column>
<apex:column headerValue="From">
<apex:inputField value="{!prod.From__c}"/>
</apex:column> 
<apex:column headerValue="To">
<apex:inputField value="{!prod.To__c}"/>
</apex:column> 
<apex:column headerValue="Forecast Quantity">
<apex:inputField value="{!prod.Forecast_Quantity__c}"/>
</apex:column> 
<apex:column headerValue="Forecast Unit">
<apex:inputField value="{!prod.Forecast_Unit__c}"/>
</apex:column> 
<apex:column headerValue="Kontakt">
<apex:inputField value="{!prod.Contact__c}"/>
</apex:column> 
<apex:column headerValue="Subunternehmen">
<apex:inputField value="{!prod.Subunternehmen__c}"/>
</apex:column> 

</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

 

THX

Chi-Towns FinestChi-Towns Finest

You are getting the error, because the id in the parameter of the VF page has to match the sObject type of the StandardController of the page. You have an opportunity id in your url, but that is not the standard controller of your VF page.

 

I hope this helps!

oodsigmaoodsigma

Hi there,

 

first of all thanks for the reply. This may be a stupid question, yet I have to ask to be sure I understood you correctly. I am getting the Oppty Id from a formula field OpportunityID__c on the custom object to make sure it is passed along. I have adjusted the code a little and a sth. new happened.

 

Error: List has more than 1 row for assignment to SObject 

 

I guess my problem now lays within the SQL query which returns > 1 record. I thought I already took care of that with the <List> but apparently...NOT. :(

 

Update Code: Controller Ext.

 

public class extForecastProducts{

// define variable
public Produkt_Ressourcen_Forecast__c ForecastProducts;

public List<Produkt_Ressourcen_Forecast__c> lstForecastProducts;

Opportunity ForecastProductsNew;

public extForecastProducts(ApexPages.StandardSetController controller) {
this.ForecastProducts= (Produkt_Ressourcen_Forecast__c)controller.getRecord();
// get Oppty Id from field in custom object where current id matches

Id Opps= [Select OpportunityID__c FROM Produkt_Ressourcen_Forecast__c
where OpportunityID__c =: ApexPages.currentPage().getParameters().get('id')].OpportunityID__c;

lstForecastProducts = (List<Produkt_Ressourcen_Forecast__c>)[

// get fields of custom object
Select Id,
Contact__c,
Cost__c, Cost_Type__c,
Forecast_Product__c,
ID__c,
Forecast_Quantity__c,
Forecast_Unit__c,
Leistung_erbracht__c,
Mitarbeiter_Rolle__c,
Opportunity_Line_Item_Id__c,
Opportunity_TS_BETA__c,
Product__c,
Product_Code__c,
Profitability__c,
Quantity__c,
Sales_Price__c,
SFDC_Lizenz_Preis__c,
Subunternehmen__c,
To__c,
Total_Cost__c,
Total_Margin__c,
Total_Price__c,
Unit__c,
OpportunityID__c

From Produkt_Ressourcen_Forecast__c
where OpportunityID__c =: Opps];
ForecastProductsNew = [Select Id, Name From Opportunity Where Id =: Opps];

}

public List<Produkt_Ressourcen_Forecast__c> getlstForecastProducts(){
return lstForecastProducts;
}
public Opportunity getForecastProductsNew(){
return ForecastProductsNew;
}

public PageReference save() {
update lstForecastProducts;
return (new ApexPages.StandardController(ForecastProductsNew)).view();
}
}

 

------------------------------------

 

Update Code: VS Page

 

<apex:page standardController="Produkt_Ressourcen_Forecast__c" tabStyle="Opportunity" recordSetVar="ProduktRessourcenForecasts" extensions="extForecastProducts"
sidebar="false" >

<apex:form >
<apex:pageBlock >
<apex:pageMessages />

<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!Save}"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</apex:pageBlockButtons>

<apex:pageBlockTable value="{!lstForecastProducts}" var="prod" id="prod_table">
<apex:column value="{!prod.Name}"/>
<apex:column headerValue="Opportunity">
<apex:inputField value="{!prod.Opportunity_TS_BETA__c}"/>
</apex:column>
<apex:column headerValue="Forecast Product">
<apex:inputField value="{!prod.Forecast_Product__c}"/>
</apex:column>
<apex:column headerValue="Leistung erbracht">
<apex:inputField value="{!prod.Leistung_erbracht__c}"/>
</apex:column>
<apex:column headerValue="Mitarbeiter Rolle">
<apex:inputField value="{!prod.Mitarbeiter_Rolle__c}"/>
</apex:column>
<apex:column headerValue="From">
<apex:inputField value="{!prod.From__c}"/>
</apex:column>
<apex:column headerValue="To">
<apex:inputField value="{!prod.To__c}"/>
</apex:column>
<apex:column headerValue="Forecast Quantity">
<apex:inputField value="{!prod.Forecast_Quantity__c}"/>
</apex:column>
<apex:column headerValue="Forecast Unit">
<apex:inputField value="{!prod.Forecast_Unit__c}"/>
</apex:column>
<apex:column headerValue="Kontakt">
<apex:inputField value="{!prod.Contact__c}"/>
</apex:column>
<apex:column headerValue="Subunternehmen">
<apex:inputField value="{!prod.Subunternehmen__c}"/>
</apex:column>

</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>


Anything that can put me in the right direction is very much appreciated.

Chi-Towns FinestChi-Towns Finest
The only stupid questions are the ones not asked!
What I was referring to was in your controller you have:
Id Opps= [Select OpportunityID__c FROM Produkt_Ressourcen_Forecast__c
where OpportunityID__c =: ApexPages.currentPage().getParameters().get('id')].OpportunityID__c;
We will get to the second error a little later, but for now, this will give you an error because I'm assuming that the id in the parameter of the page is an Opportunity id. But your VF page has:
<apex:page standardController="Produkt_Ressourcen_Forecast__c"
which causes the system to look for an id of Produkt_Ressourcen_Forecast__c type in your url. So that is why you are getting the first error.
The second issue is with the first line I copied above. You would have to put limit 1 for it to not throw an error, but even if you did, it doesn't accomplish anything. The code is basically putting the id you already have in your parameter back into the variable. You will have to change your 'id' to a Produkt_Ressourcen_Forecast__c id and then you would have something like this in your code
public extForecastProducts(ApexPages.StandardSetController controller) {
this.ForecastProducts= (Produkt_Ressourcen_Forecast__c)controller.getRecord();
// get Oppty Id from field in custom object where current id matches
Id oppId = ForecastProducts.OpportunityID__c;
you wouldn't have to perform a query and you would not get an error.
If I understood more or what you are trying to accomplish with your code and possibly would help you further.
Again, I hope this helps!
oodsigmaoodsigma

Hi Dominic,

 

thanks so much for your reply!

 

I'll describe the scenario more detailed. I have created a custom object Produkt_Ressourcen_Forecast__c as child object to an Opportunity.

What I'd love to have is a page that allows me to edit/save all records of the custom object at once. Basically the same functionality you'll find for Opportunity Line items. 

 

I tried the following so far:

1. Using standardController for Opportunity - the save didn't cause it referred to the Oppty rather than the custom object.

2. Using standardController for Produkt_Ressourcen_Forecast__c - it displayed all custom objects for all Oppties

 

Which is where the controller should come into play to make sure the VS page only displays the custom objects related to the Opportunity I currently view by passing on the Id.

----------------

 

With a little help from a coworker we now corrected the code. And here comes the BUT. I am not getting an error anymore yet the list won't show any record. 

 

public class extForecastProducts{


// define variable
public Produkt_Ressourcen_Forecast__c ForecastProducts;

public List<Produkt_Ressourcen_Forecast__c> lstForecastProducts;

Opportunity ForecastProductsNew = new Opportunity();

public extForecastProducts(ApexPages.StandardSetController controller) {
this.ForecastProducts= (Produkt_Ressourcen_Forecast__c)controller.getRecord();
// get Oppty Id from field in custom object where current id matches
Id Opps = ForecastProducts.OpportunityID__c;
/*
Id Opps= [Select OpportunityID__c FROM Produkt_Ressourcen_Forecast__c
where OpportunityID__c =: ApexPages.currentPage().getParameters().get('id')].OpportunityID__c;
*/
List<Opportunity> ForecastProductsNew2 = new List<Opportunity>();
lstForecastProducts = (List<Produkt_Ressourcen_Forecast__c>)[
// get fields of custom object
SELECT Id, Contact__c, Cost__c, Cost_Type__c,
Forecast_Product__c,ID__c, Forecast_Quantity__c,
Forecast_Unit__c, Leistung_erbracht__c, Mitarbeiter_Rolle__c,
Opportunity_Line_Item_Id__c, Opportunity_TS_BETA__c,
Product__c, Product_Code__c,
Profitability__c, Quantity__c,
Sales_Price__c, SFDC_Lizenz_Preis__c,
Subunternehmen__c, To__c,
Total_Cost__c, Total_Margin__c,
Total_Price__c, Unit__c,
OpportunityID__c FROM Produkt_Ressourcen_Forecast__c WHERE OpportunityID__c =: Opps];
string oppsid = Opps;
ForecastProductsNew2 = [SELECT Id FROM Opportunity WHERE Id =: oppsid LIMIT 1];
}

public List<Produkt_Ressourcen_Forecast__c> getlstForecastProducts(){
return lstForecastProducts;
}
public Opportunity getForecastProductsNew(){
return ForecastProductsNew;
}

public PageReference save() {
update lstForecastProducts;
return (new ApexPages.StandardController(ForecastProductsNew)).view();
}
}

 

Again...thanks a lot for helping out.

Chi-Towns FinestChi-Towns Finest
I'll put together a sample class to see if this helps:

public class extForecastProducts

{

// define variable
public Produkt_Ressourcen_Forecast__c ForecastProducts;
public List<Produkt_Ressourcen_Forecast__c> lstForecastProducts {get; set;}

public Opportunity ForecastProductsNew {get; set;}

public extForecastProducts(ApexPages.StandardSetController controller)

{
     this.ForecastProducts= (Produkt_Ressourcen_Forecast__c)controller.getRecord();
     // get Oppty Id from field in custom object where current id matches, if oppId is null, then you have to query for that field but it should be populated
     Id oppId = ForecastProducts.OpportunityID__c;

     System.debug(oppId);

     ForecastProductsNew = loadOpportunity(oppId);
     

     lstForecastProducts = [SELECT Id, Contact__c, Cost__c, Cost_Type__c, Forecast_Product__c,ID__c, Forecast_Quantity__c, Forecast_Unit__c, Leistung_erbracht__c, Mitarbeiter_Rolle__c, Opportunity_Line_Item_Id__c, Opportunity_TS_BETA__c, Product__c, Product_Code__c, Profitability__c, Quantity__c, Sales_Price__c, SFDC_Lizenz_Preis__c, Subunternehmen__c, To__c, Total_Cost__c, Total_Margin__c, Total_Price__c, Unit__c,

OpportunityID__c

FROM Produkt_Ressourcen_Forecast__c

WHERE OpportunityID__c =: oppId];
}

 

private Opportunity loadOpportunity(Id i)

{

     try

     {

          // You can add whatever fields you need to this query

          return [Select Id, Name From Opportunity Where Id =: i];

     }

     catch (Exception e)

     {

          return new Opportunity();

     }

}


public PageReference save() {
update lstForecastProducts;
return (new ApexPages.StandardController(ForecastProductsNew)).view();
}
}

 

try this and it is mainly just a template but it should help.

oodsigmaoodsigma

Hi Dominic,

 

again thanks a lot for helping out and even writing a test class. I've implemented this into our org, yet I the objects are not displayed. I checked profiles/ accesses, the ID passed to Produkt_Ressourcen_Forecast__c and the reference to the listForecastProducts on the VS page. So far I cannot see the issue. I will of course continue looking :)-

Dirk GronertDirk Gronert

Can you pls share the debug log from the run of Chi-Towns Finest class pls?

Chi-Towns FinestChi-Towns Finest

Can you put a sample of your VF page? I am not understanding why you are not getting results shown.