You need to sign in to do that
Don't have an account?
Amit Gaur 8
How to Edit & Save Opportunity Line Items record in Apex Class
I want to edit and Save Opportunity Line Items record in the same VF page but I don't know what to write in Edit Method. Please Help!!
Controller Class-
public class SearchOpportunity
{
public list<opportunity> oppList{get;set;}
public opportunity opp{get;set;}
String query='';
public String oliID{get;set;}
public searchOpportunity()
{
oppList=new list<opportunity>();
opp = new opportunity();
}
public void Search()
{
query='select id,name,stagename,Type,(Select id,ProductCode,ListPrice,UnitPrice,Quantity from OpportunityLineItems) from opportunity where';
if(opp.StageName!=Null)
{
query=query+' stageName = \''+ opp.stagename+'\' AND';
}
if(opp.Type!=Null)
{
query=query+' type = \''+ opp.TYPE+'\' AND';
}
if(opp.AccountId!=Null)
{
query=query+' AccountId = \''+ opp.AccountId+'\' AND';
}
query=query.removeEnd('where');
query=query.removeEnd('AND');
System.Debug(query);
opplist = Database.query(query);
}
public void Edit()
{
OpportunityLineItem ol =[Select unitprice, quantity from OpportunityLineItem where Id=: oliID];
}
public void Erase()
{
OpportunityLineItem ol =[Select Id from OpportunityLineItem where Id=: oliID];
delete ol;
search();
}
public void Save()
{
OpportunityLineItem ol =[Select Id from OpportunityLineItem where Id=: oliID];
update ol;
}
}
VF Page-
<apex:page controller="SearchOpportunity">
<apex:form id="frmid">
<apex:pageBlock >
<apex:pageBlockSection title="Search Opportunity">
<apex:inputField value="{!opp.StageName}"/>
<apex:inputField value="{!opp.type}"/>
<apex:inputField value="{!opp.accountid}"/>
<apex:commandButton value="Search" action="{!Search}" reRender="frmid"/>
</apex:pageBlockSection>
</apex:pageBLock>
<apex:pageBlock id="oppTable">
<apex:pageblockSection title="Opportunity Detail">
<apex:outputPanel id="panel1">
<apex:repeat value="{!opplist}" var="o" >
<table>
<tr>
<td><b>{!o.name}</b></td>
<td>{!o.stagename}</td>
<td>{!o.type}</td>
</tr>
</table>
<apex:pageblocktable value="{!o.opportunitylineitems}" var="oli">
<apex:column >
<apex:commandButton value="Edit" Action="{!Edit}">
<apex:param name="id" value="{!oli.Id}" assignTo="{!oliID}"/>
</apex:commandButton>
<apex:commandButton action="{!Erase}" value="Delete" reRender="panel1">
<apex:param name="id" value="{!oli.id}" assignTo="{!oliID}" />
</apex:commandButton>
</apex:column>
<apex:column value="{!oli.id}"/>
<apex:column value="{!oli.productcode}"/>
<apex:column value="{!oli.listprice}"/>
<apex:column value="{!oli.unitprice}"/>
<apex:column value="{!oli.quantity}"/>
<apex:column >
<apex:commandButton action="{!Save}" value="Save" reRender="panel1">
<apex:param name="id" value="{!oli.id}" assignTo="{!oliID}" />
</apex:commandButton>
</apex:column>
</apex:pageblocktable>
</apex:repeat>
</apex:outputPanel>
</apex:pageblockSection>
</apex:pageblock>
</apex:form>
</apex:page>
Controller Class-
public class SearchOpportunity
{
public list<opportunity> oppList{get;set;}
public opportunity opp{get;set;}
String query='';
public String oliID{get;set;}
public searchOpportunity()
{
oppList=new list<opportunity>();
opp = new opportunity();
}
public void Search()
{
query='select id,name,stagename,Type,(Select id,ProductCode,ListPrice,UnitPrice,Quantity from OpportunityLineItems) from opportunity where';
if(opp.StageName!=Null)
{
query=query+' stageName = \''+ opp.stagename+'\' AND';
}
if(opp.Type!=Null)
{
query=query+' type = \''+ opp.TYPE+'\' AND';
}
if(opp.AccountId!=Null)
{
query=query+' AccountId = \''+ opp.AccountId+'\' AND';
}
query=query.removeEnd('where');
query=query.removeEnd('AND');
System.Debug(query);
opplist = Database.query(query);
}
public void Edit()
{
OpportunityLineItem ol =[Select unitprice, quantity from OpportunityLineItem where Id=: oliID];
}
public void Erase()
{
OpportunityLineItem ol =[Select Id from OpportunityLineItem where Id=: oliID];
delete ol;
search();
}
public void Save()
{
OpportunityLineItem ol =[Select Id from OpportunityLineItem where Id=: oliID];
update ol;
}
}
VF Page-
<apex:page controller="SearchOpportunity">
<apex:form id="frmid">
<apex:pageBlock >
<apex:pageBlockSection title="Search Opportunity">
<apex:inputField value="{!opp.StageName}"/>
<apex:inputField value="{!opp.type}"/>
<apex:inputField value="{!opp.accountid}"/>
<apex:commandButton value="Search" action="{!Search}" reRender="frmid"/>
</apex:pageBlockSection>
</apex:pageBLock>
<apex:pageBlock id="oppTable">
<apex:pageblockSection title="Opportunity Detail">
<apex:outputPanel id="panel1">
<apex:repeat value="{!opplist}" var="o" >
<table>
<tr>
<td><b>{!o.name}</b></td>
<td>{!o.stagename}</td>
<td>{!o.type}</td>
</tr>
</table>
<apex:pageblocktable value="{!o.opportunitylineitems}" var="oli">
<apex:column >
<apex:commandButton value="Edit" Action="{!Edit}">
<apex:param name="id" value="{!oli.Id}" assignTo="{!oliID}"/>
</apex:commandButton>
<apex:commandButton action="{!Erase}" value="Delete" reRender="panel1">
<apex:param name="id" value="{!oli.id}" assignTo="{!oliID}" />
</apex:commandButton>
</apex:column>
<apex:column value="{!oli.id}"/>
<apex:column value="{!oli.productcode}"/>
<apex:column value="{!oli.listprice}"/>
<apex:column value="{!oli.unitprice}"/>
<apex:column value="{!oli.quantity}"/>
<apex:column >
<apex:commandButton action="{!Save}" value="Save" reRender="panel1">
<apex:param name="id" value="{!oli.id}" assignTo="{!oliID}" />
</apex:commandButton>
</apex:column>
</apex:pageblocktable>
</apex:repeat>
</apex:outputPanel>
</apex:pageblockSection>
</apex:pageblock>
</apex:form>
</apex:page>
A few ways I can think of:
One - always delete the line items on child opportunity and create afresh on every change on the parent, as a copy from the parent. Too much DML.
Two - create a custom formula field on OpportunityLineItem which is a composite key, eg PriceBookEntryId+Quantity, which will evaluate to the same on parent and child OpportunityLineItems and therefore you can match using the formula field composite key.
Three - (Recommended) If you can be sure that a Product is added only once, then you can match on the PriceBookEntryId, because this will be the same on Parent and Child Opportunity Line Items. This sounds the most promising provided the precondition is met.
Four - create a hidden text field on OpprtunityLineItem, into which you stamp the value of the Parent OpportunityLineItem at create. Then for every subsequent change you can match by the parent OpportunityLineItem Ids that are changing and accordingly update all related child OpportunityLineItem Ids.
Sample Code for Solution Four :
Create a hidden field ParentLineItemId__c on OpportunityLineItem (Text, 18) Then in your inner for loop, you can set this
Follow these steps,
1) instead of inputField use something like outputtext or outputlabel (in non edit mode) on page load
2) once user clicks on the edit button instead outputtext render inputField so that row will come to edit format
3) once user clicks on the save you can either save all the reocrds or records in edit mode
for saving you can do like this.
public void Save()
{
update opplist; // should not query as we need to update the list from page instead from DB
}
let me konw, if it helps you or need any help :)
shiva.sfdc.backup@gmail.com