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
lizkshannonlizkshannon 

default field values when adding opportunity line items

Hi,

 

I'm not a developer, but I'm attempting to learn since I've reached a point where I need code to customize and automate further.  I've created a custom "Sales Price" field for Opportunity Products that I am using to replace the standard Sales Price field.  I want the custom field to default with the price book entry list price (unitprice) value as does the standard Sales Price field.  Then I have the standard Sales Price field getting updated to equal the custom Sales Price times the number of month terms (custom field that will be updated at Opportunity level and automatically populated in reflective custom field on Opportunity Products via trigger).  I've created triggers for both the Sales Price value to default and the Month Terms to default, but neither seems to be working now.   Below is the trigger for the Sales Price value when creating a new opportunity line item.  I could have sworn this worked last Friday and now doesn't.  Not sure how to get the price to default when adding a new product line item?  It should only default when adding new since I don't want it to override any amount that they put in and save. But it also needs to work if they go back into the opp and add additional items later.  Any input on this is greatly appreciated. I've spent hours searching other posts in the community and all the other documentation, but I don't have that natural developer brain, and I'm banging my head now!

 

trigger SalesPricecustom on OpportunityLineItem (before insert) {
    Set<Id> pbeIds = new Set<Id>();
        for (OpportunityLineItem oli : Trigger.new) 
        pbeIds.add(oli.pricebookentryid);
        
    Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>(
        [select UnitPrice from pricebookentry 
         where id in :pbeIds]);     
            
for (OpportunityLineItem oli :trigger.new){
     if(pricebookentry.unitprice <> null && oli.sales_price__c == null){
    
    oli.sales_price__c = entries.get(oli.pricebookEntryId).UnitPrice;  
  }
}} 

 

Thanks!

RustanRustan

The problem is right here:

 

 if(pricebookentry.unitprice <> null && oli.sales_price__c == null){
    
    oli.sales_price__c = entries.get(oli.pricebookEntryId).UnitPrice;  
  }

 

 

You are asking it to be both null and not null. Actually, you can just delete the if statement period and call it a day.

lizkshannonlizkshannon

Thank you for the quick reply!  I deleted that line, but it's still not appearing in the field on the add product screen.

 

Any other thoughts?  I also have a trigger to update the month terms from the Opportunity and that one is not working either.  Is it okay to have two separate triggers both defaulting values when adding products?

 

thanks again!

RustanRustan

Try this and see if it works and I would try to put all the triggers for an object in one trigger, if it was me.

trigger SalesPricecustom on OpportunityLineItem (after insert) {
Set<Id> pbeIds = new Set<Id>();
for (OpportunityLineItem oli : Trigger.new)
pbeIds.add(oli.pricebookentryid);

Map<Id, double> entries = new Map<Id, double>();

for(PricebookEntry pbe : [select id, UnitPrice from PricebookEntry where id IN : pbeIds)
{
entries.put(pbe.id, pbe.UnitPrice);
}


list<OpportunityLineItem> upOLI = list<OpportunityLineItem>();
for(OpportunityLineItem oli: [select id, Sales_Price__c, pricebookEntryId from OpportunityLineItem where pricebookEntryId IN : pbeIds])
{
oli.sales_price__c = entries.get(oli.pricebookEntryId)
upOLI.add(oli);
}
update upOLI;
}

lizkshannonlizkshannon

Again thanks for getting right back.

I got an error here
    list<OpportunityLineItem> upOLI = list<OpportunityLineItem>();

Should that be  = new list?  had a few minor ] and ; additions and was able to save, but it's still not working :(

 

trigger SalesPricecustom on OpportunityLineItem (after insert) {

Set<Id> pbeIds = new Set<Id>();
for (OpportunityLineItem oli : Trigger.new)
pbeIds.add(oli.pricebookentryid);

Map<Id, double> entries = new Map<Id, double>();

for(PricebookEntry pbe : [select id, UnitPrice from PricebookEntry where id IN : pbeIds])
{
entries.put(pbe.id, pbe.UnitPrice);
}


list<OpportunityLineItem> upOLI = new list<OpportunityLineItem>();
for(OpportunityLineItem oli: [select id, Sales_Price__c, pricebookEntryId from OpportunityLineItem where pricebookEntryId IN : pbeIds])
{
oli.sales_price__c = entries.get(oli.pricebookEntryId); 
upOLI.add(oli);
}
update upOLI;
}

 



RustanRustan

One question, this may sound like a stupid question but it's happened to me a few times. Make sure that the trigger is active. 

 

If it is active, try adding some system.debug and then monitor the debug log to try to pinpoint where the problem is.

lizkshannonlizkshannon

Not a stupid question and I wish it were that simple of a fix!  It's active :).  I also deactivated the other trigger to see if they weren't playing well together, but that wasn't it either.  I'm looking into debug code. I don't know how to write it, but will see what I can do!  Thanks.

RustanRustan

 

Try this

 

trigger SalesPricecustom on OpportunityLineItem (after insert) {

Set<Id> pbeIds = new Set<Id>();
for (OpportunityLineItem oli : Trigger.new)
{
pbeIds.add(oli.pricebookentryid);
system.debug('adding to pbeIds ------>' + oli.pricebookentry.id);
}

Map<Id, double> entries = new Map<Id, double>();

for(PricebookEntry pbe : [select id, UnitPrice from PricebookEntry where id IN : pbeIds])
{
entries.put(pbe.id, pbe.UnitPrice);
system.debug('putting in a map id------>' + pbe.id);
system.debug('putting in a map value------>' + pbe.UnitPrice);
}


list<OpportunityLineItem> upOLI = new list<OpportunityLineItem>();
for(OpportunityLineItem oli: [select id, Sales_Price__c, pricebookEntryId from OpportunityLineItem where pricebookEntryId IN : pbeIds])
{
oli.sales_price__c = entries.get(oli.pricebookEntryId);
system.debug('check if the value was assigned----->' + oli.Sales_Price__c);
upOLI.add(oli);
}
update upOLI;
}

 

lizkshannonlizkshannon

Here is my newest thought...  Instead of pulling the Unit Price from the price book entry, I could just pull in the List Price field from the  Opportunity Line Item (Opportunity Product) object since that List Price is the same.  I would think that would simplify everything and it could be as simple as ...?

 

 

trigger SalesPricecustom on OpportunityLineItem (before insert) {
        for (OpportunityLineItem oli : Trigger.new) 
        if (oli.ListPrice <> null){
      oli.Sales_Price__c = oli.ListPrice;
      }
      }

 

 But this still does not work.  Does it have something to do with before insert for opportunity line item? when is it considered an opportunity line item?  I'm wanting it to appear in the screen where you enter your quantity and sales price  etc after selecting the products to add.

 

Add Products screen

 

lizkshannonlizkshannon

I found this - http://www.salesforce.com/us/developer/docs/dbcom_apex/dbcom_apex_language_reference.pdf  PAGE 83 is exactly what I'm trying to do with Unit Price instead of product color.  I used this code and still no luck, so I need to figure out what else could be interfering.  Will try that debug...

RustanRustan

Wait, are you trying to have the value to be pre-populated with a suggested value then it could be changed before they save it?

 

If that's the case, you can't use a trigger for that. You will have to create a visualforce page with either a custom controller or controller extension to override the Edit All product standard page.

lizkslizks

That's exactly what I'm trying to do, so good to know it can't be done that way!  Well, not good in general, but at least I know now!  So now I'll attempt to learn a visual force page...Thank you for letting me know. Sorry I didn't explain it properly from start. 

lizkshannonlizkshannon

Ok. I think I have the visualforce page, but am stuck on the controller extension.  I don't know what I'm doing on that.  I have a start, but I know I need to add the pieces about looking up the related Opportunity and related price book entries/products.  I also need to add the logic to have the Sales_Price__c field default to UnitPrice and have the Month_Terms__c default to the Opportunity Month Terms.  Any help with finishing this off?

 

Here is the VF page:

 

<apex:page standardController="Opportunity"> extensions="opportunityProductExtension">
    <apex:form >
         <apex:pageBlock title="Selected Products" id="selected">
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save"/>
                <apex:commandButton action="{!cancel}" value="Cancel"/>
            </apex:pageBlockButtons>
            <apex:pageBlockTable value="{!Opportunity.OpportunityLineItems}" var="lineItem">
                <apex:column headerValue="Product Name" value="{!lineItem.PriceBookEntry.Product2.Name}"/>
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                         <apex:inputField value="{!lineItem.Quantity}" style="width:70px" required="true" onkeyup="refreshTotals();"/>
                        </apex:column> 
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Sales_Price__c.Label}"> <apex:outputField value="!lineItem.PriceBookEntry.UnitPrice"/>
                        <apex:inputField value="{!lineItem.Sales_Price__c}" style="width:70px" required="true"/>
                        </apex:column>
                     <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Month_Terms__c.Label}"> <apex:outputField value="{!lineItem.Opportunity.Month_Terms__c}"/>
                        </apex:column>
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.UnitPrice.Label}"> <apex:outputField value="{!lineItem.PriceBookEntry.UnitPrice}"/>
                        </apex:column>
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Type_of_Sale__c.Label}">
                        <apex:inputField value="{!lineItem.Type_of_Sale__c}" style="width:70px" required="true"/>
                        </apex:column>
                    <apex:column headerValue="List Price"> <apex:outputField value="{!lineItem.PriceBookEntry.UnitPrice}"/>
                     </apex:column>
             </apex:pageblocktable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

and here is the class extension that is incomplete and ugly:

 

public with sharing class opportunityProductExtension {

    public Opportunity Opp {get;set;}
    public opportunityLineItem[] lineItem {get;set;}
    public priceBookEntry[] AvailableProducts {get;set;}
     
    Id oppId;

    // we are extending the OpportunityLineItem controller, so we query to get the parent OpportunityId
    public opportunityProductExtension(ApexPages.StandardController controller) {
        oppId = [select Id, OpportunityId from OpportunityLineItem where Id = :controller.getRecord().Id limit 1].OpportunityId;
    }
    
    // then we redirect to our desired page with the Opportunity Id in the URL
    public pageReference redirect(){
        return new PageReference('/apex/opportunityProductEdit?id=' + oppId);
    }

}

 

Begging for help since I've spent wayyyy too long on this already.

Thanks!