• MC2014
  • NEWBIE
  • 50 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 9
    Questions
  • 14
    Replies
I have this VF page, with a contact look up field when selected it pre-populate shipping address fields based on contact select. For this example I have two "John Smith" contact records. 
If I were to either enter or copy the entire name I get this that pop ups which is expect: before enter to select

When I hit enter this happens: User-added image  

The my recent items stay there, I can't click on it nor can I even click on that drop-down menu.
This happens all the time with Firefox, sometimes with Chrome, and never with IE.
Does this ever happens to anyone before? I am using actionRegion in very common way that is pre-populate fields based on look up field selected.

Below is the VF code:
<apex:actionRegion >  
                <apex:pageBlockSection id="Shipto" title="2) Shipment Details" collapsible="false">     
                    <apex:inputField value="{!case.ShipToContact__c}" required="true">
                        <apex:actionSupport event="onchange" action="{!ShipToPopulated}" rerender="Shipto, msgs"/>
                    </apex:inputField>   
                    <apex:outputField value="{!case.Ship_To_Account__c}"/> 
                    <apex:inputField value="{!case.ShippingStreet__c}"/> 
                    <apex:inputField value="{!case.ShippingCity__c}"/> 
                    <apex:inputField value="{!case.ShippingState1__c}"/> 
                    <apex:inputField value="{!case.ShippingPostalCode__c}"/>                                              
                </apex:pageBlockSection>
            </apex:actionRegion>


 
  • December 22, 2014
  • Like
  • 0
I have a public site page form that creates a case and assigns it to the owner that is query within Apex. Since, its is a public site it doesn't query anything from the user object.

Using "Site.getAdminId()" doesn't work in my case, since I am the site administrator that is not what I want.

16:09:31.169 (169671978)|SOQL_EXECUTE_BEGIN|[119]|Aggregations:0|SELECT Id FROM User WHERE Name = 'Salesforce Administrators' LIMIT 1
16:09:31.189 (189902826)|SOQL_EXECUTE_END|[119]|Rows:0
16:09:31.190 (190228383)|SYSTEM_MODE_EXIT|false
16:09:31.190 (190383656)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject


  • September 09, 2014
  • Like
  • 0
I borrow  a good part of michalforce receipe (http://www.michaelforce.org/recipeView?id=a0G30000006eVxVEAU) and used this shopping cart code work with creating a case.

So whenever, I added a new product to the shopping cart, the quantity doesn't get saved. The quantity is stored in a wrapper class, and if system.debug upon saving it shows that PricebookEntry object and quantity is in the "shoppingCart2" wrapper list, somehow {!s.productQuantity} in VF isn't being pulled.?

Here is the entire Apex:
public with sharing class InternalFurfillment2 {

    public String searchString {get;set;}

    private List<PriceBookWrapper> forDeletion2 = new List<PriceBookWrapper>();
    public List<PriceBookWrapper> shoppingCart2 {get;set;}
    
    public priceBookEntry[] AvailableProducts {get;set;}
    public String toSelect {get; set;}
    public String toUnselect {get; set;}
    public Boolean overLimit {get;set;}
    
    public string priceBookName = 'Internal Price Book';
    
    private ApexPages.StandardController stdController;    
    private Case caseObject;
      
    public InternalFurfillment2(ApexPages.StandardController controller) {
        this.caseObject = (Case) controller.getRecord();  
        shoppingCart2 = new List<PriceBookWrapper>();

        updateAvailableList();       
    }

    public void updateAvailableList() {
        
        // We dynamically build a query string and exclude items already in the shopping cart
        String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Family, Product2.IsActive, Product2.Description, UnitPrice, Product2.Vendor__c from PricebookEntry where IsActive=true and PricebookEntry.Pricebook2.Name = \'' + priceBookName + '\'';
        system.debug('qString begin==>' + qString);
        // note that we are looking for the search string entered by the user in the name OR description
        // modify this to search other fields if desired
        if(searchString!=null){
            qString+= ' and (Product2.Name like \'%' + searchString + '%\' or Product2.Description like \'%' + searchString + '%\')';
        }
        
        Set<Id> selectedEntries = new Set<Id>();
        
        for(PriceBookWrapper d : shoppingCart2){
            system.debug('d==>' + d);
            selectedEntries.add(d.pbeEntry.Id);
        }
        system.debug('selectedEntries==>' + selectedEntries);
               
        if(selectedEntries.size()>0){
            String tempFilter = ' and Id not in (';
            for(Id i : selectedEntries){
                tempFilter+= '\'' + (String)i + '\',';
            }
            String extraFilter = tempFilter.substring(0,tempFilter.length()-1);
            extraFilter+= ')';
            
            qString+= extraFilter;
        }
        
        qString+= ' order by Product2.Name';
        qString+= ' limit 101';
        
        system.debug('qString:' +qString);        
        AvailableProducts = database.query(qString);
        
        // We only display up to 100 results... if there are more than we let the user know (see vf page)
        if(AvailableProducts.size()==101){
            AvailableProducts.remove(100);
            overLimit = true;
        }
        else{
            overLimit=false;
        }
    }
    
    public void addToShoppingCart(){
        system.debug('AvailableProducts==>' + AvailableProducts);
        system.debug('shopping cart outside top==>' + ShoppingCart2); 
        // This function runs when a user hits "select" button next to a product    
        for(PricebookEntry d : AvailableProducts){
            if((String)d.Id==toSelect){
                shoppingCart2.add(new PriceBookWrapper(d,0)); system.debug('shopping cart inside==>' + ShoppingCart2);
                break;
            }
        }system.debug('shopping cart outside==>' + ShoppingCart2);       
        updateAvailableList();  
    }
    

    public PageReference removeFromShoppingCart(){    
        // This function runs when a user hits "remove" on an item in the "Selected Products" section            Integer count = 0;    
        for(PriceBookWrapper d : shoppingCart2){
            if((String)d.pbeEntry.Id==toUnselect){            
                if(d.pbeEntry.Id!=null)
                    forDeletion2.add(d);            
                shoppingCart2.remove(count);
                break;
            }
            count++;
        }        
        updateAvailableList();       
        return null;
    }
    
    public PageReference onSave(){        
        system.debug('shoppingCart2 submit==>' + shoppingCart2);
               return null;
    }
         
     public class PriceBookWrapper{  
         public Integer productQuantity {get;set;}  
         public PriceBookEntry pbeEntry {get;set;}  
         
         public PriceBookWrapper(PriceBookEntry pbeEntry, Integer productQuantity){  
             this.pbeEntry = pbeEntry;  
             this.productQuantity = productQuantity; 
         }      
    }  
}


The portion of VF that where quantity should be displaying:
..	
<apex:pageBlock title="My Content">	
		<apex:outputPanel id="mainBody">
        
<!-- this is the upper table... a.k.a. the "Shopping Cart"-->
            <!-- notice we use a lot of $ObjectType merge fields... I did that because if you have changed the labels of fields or objects it will reflect your own lingo -->
            <apex:pageBlockSection title="{!$ObjectType.Product2.LabelPlural} Selection" id="selected" columns="1"> 
                <apex:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                <apex:pageblockTable value="{!shoppingCart2}" var="s">
                
                    <apex:column >
                        <apex:commandLink value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true">
                            <!-- this param is how we send an argument to the controller, so it knows which row we clicked 'remove' on -->
                            <apex:param value="{!s.pbeEntry.Id}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.pbeEntry.Product2.Name}"/>
                    
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputText value="{!s.productQuantity}" style="width:70px" required="true" onkeyup="refreshTotals();"/>
                    </apex:column>
                        <!--   -->
             
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description.Label}">
                        <apex:outputField value="{!s.pbeEntry.Product2.Family}"/>    
                    </apex:column>
                   
                </apex:pageblockTable>
         </apex:pageBlock>
...


This is the entire VF page:

<apex:form>
	<apex:pageBlock title="My Content">	
		<apex:outputPanel id="mainBody">
			<apex:pageBlockSection title="{!$ObjectType.Product2.LabelPlural} Selection" id="selected" columns="1"> 
                <apex:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                <apex:pageblockTable value="{!shoppingCart2}" var="s">
                
                    <apex:column >
                        <apex:commandLink value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true">
                            <!-- this param is how we send an argument to the controller, so it knows which row we clicked 'remove' on -->
                            <apex:param value="{!s.pbeEntry.Id}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.pbeEntry.Product2.Name}"/>
                    
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputText value="{!s.productQuantity}" style="width:70px" required="true" onkeyup="refreshTotals();"/>
                    </apex:column>
                        <!--   -->
             
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description.Label}">
                        <apex:outputField value="{!s.pbeEntry.Product2.Family}"/>    
                    </apex:column>
                   
        </apex:pageblockTable>
    </apex:pageBlock>
    
		<!--this is the lower table: search bar and search results-->
		<apex:pageBlock >          
			<apex:outputPanel styleClass="search">
				Search for {!$ObjectType.Product2.LabelPlural}:
			</apex:outputPanel>

			<apex:actionRegion renderRegionOnly="false" immediate="true">
			
				<apex:actionFunction name="fetchResults" action="{!updateAvailableList}" reRender="searchResults" status="searchStatus"/>
				
				<!-- here we invoke the scripting to get out fancy 'no button' search bar to work -->
				<apex:inputText value="{!searchString}" onkeydown="if(event.keyCode==13){this.blur();}else{resetTimer();}" style="width:300px"/>
				&nbsp;&nbsp;
				<i>
					<!-- actionStatus component makes it easy to let the user know when a search is underway -->
					<apex:actionStatus id="searchStatus" startText="searching..." stopText=" "/>
				</i>
				
			</apex:actionRegion>
		
			<br/>
			<br/>
		
			<apex:outputPanel id="searchResults">
			
				<apex:pageBlockTable value="{!AvailableProducts}" var="a">
				
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Name.Label}" value="{!a.Product2.Name}" />
					
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Family.Label}" value="{!a.Product2.Family}"/>
					
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Description.Label}" value="{!a.Product2.Description}"/>
					
					<apex:column >
						<!-- command button in a column... neato -->
						<apex:commandButton value="Select" action="{!addToShoppingCart}" reRender="selected,searchResults" immediate="true">
							<!-- again we use apex:param to be able to tell the controller which row we are working with -->
							<apex:param value="{!a.Id}" assignTo="{!toSelect}" name="toSelect"/>
						</apex:commandButton>
					</apex:column>
					
				</apex:pageBlockTable>
				
				<!-- We put up a warning if results exceed 100 rows -->
				<apex:outputPanel styleClass="fyi" rendered="{!overLimit}">
					<br/>
					Your search returned over 100 results, use a more specific search string if you do not see the desired {!$ObjectType.Product2.Label}.
					<br/>
				</apex:outputPanel>
				
				</apex:outputPanel>
				</apex:pageBlock>
			</apex:pageBlockSection>
		</apex:outputPanel>

		<apex:pageBlockSectioncolumns="1">
				   <apex:outputPanel layout="block" style="align: center">
			   <apex:commandButton action="{!onSave}" value="Save"/>
			</apex:outputPanel>

		</apex:pageBlockSection> 
		</apex:pageBlock>
    </apex:form>

</apex:page>





  • August 27, 2014
  • Like
  • 0
What tools, if any, for QA in a production org. that it automatically creates an opportunity, add product, close it... etc as if I were a regular user.
  • August 18, 2014
  • Like
  • 0
I made sure that under develop -> case -> custom settings > Notify Case Owners when Case Ownership Changes is unchecked.

When I change owner through a before update trigger it ends up sending out an email to the new owner. Any thoughts?

trigger CaseTrigger on Case (before update) {
	
	for(Case c : trigger.new) {
		c.owner = xxx;
	}

}




  • August 07, 2014
  • Like
  • 0
In my apex, when a contact look up field is selected, it does a query and fill in the in corresponding visual force page inputfield on the form.

When I hit the save button, those field don't get saved,  however, the other fields like descpription do.  Am I left only  to using getter/setters to capture that data in Apex?

Here is the code.

<apex:page standardcontroller="Case" extensions="Internal">
    <apex:form >
    <apex:pageMessages id="msgs"/>
        <apex:pageBlock title="My Content">
            <apex:actionRegion >    
                <apex:pageBlockSection id="Shipto" title="Ship To Information">    
                    <apex:outputField value="{!case.Ship_To_Account__c}"/>       
                    <apex:inputField value="{!case.ShipToContact__c}">
                        <apex:actionSupport event="onchange" action="{!ShipToPopulated}" rerender="Shipto, msgs"/>
                    </apex:inputField> 
                    <apex:inputField value="{!case.Shipping_Address__c}"/> 
                    <apex:inputField value="{!case.ShippingCity__c}"/> 
                    <apex:inputField value="{!case.ShippingState__c}"/> 
                    <apex:inputField value="{!case.ShippingPostalCode__c}"/> 
                    <apex:inputField value="{!case.Shipping_Country__c}"/>                                                
                </apex:pageBlockSection>
            </apex:actionRegion>
            <apex:pageBlockSection title="My Content Section2" columns="1">
                <apex:inputField value="{!case.Description}" style="width: 90%; min-height: 100px" label="Special Instructions:"/>    
                <apex:outputPanel layout="block" style="align: center">
                    <apex:commandButton action="{!save}" value="Submit" style="align: center;"/>
                </apex:outputPanel>

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

public with sharing class Internal {
...
    public InternalFurfillment(ApexPages.StandardController controller) {
        this.caseObject = (Case) controller.getRecord();
    }

....

    public PageReference save(){
     // a bunch of logic.. but ultimately
     insert caseRecord;
     return null;
    }

....
//function where I populate those fields.
 public void ShipToPopulated() {
     
         Contact con = [select c.AccountId, c.Account.Name, c.MailingStreet, c.MailingState, c.MailingPostalCode, c.MailingCity, c.MailingCountry from Contact c where id=:caseObject.ShipToContact__c];
         
         caseObject.Ship_To_Account__c = con.AccountId;
         caseObject.Shipping_Address__c = con.MailingStreet;
         caseObject.ShippingCity__c = con.MailingCity;
         caseObject.ShippingState__c = con.MailingState;
         caseObject.ShippingPostalCode__c = con.MailingPostalCode;
         caseObject.Shipping_Country__c = con.MailingCountry;
     }


  • August 01, 2014
  • Like
  • 0
So I am playing around with LREngine library, a roll up summary alternative in apex by Tgerm.com.

This is the query it hows up in debug
SELECT OpportunityId, Sum(TotalPrice) lre0 FROM OpportunityLineItem WHERE OpportunityId in :masterIds AND Product2.Class__c = 'Science' GROUP BY OpportunityId

I would get this exception:
System.QueryException: No such relation 'Product2' on entity 'OpportunityLineItem'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.

The thing is if I were to execute that query in Query Editior, it execute fine. Is it cause It is using database.query call?





We have serveral triggersdating back from the days before my time, many have been failing and with similar errors.
They all  has always worked and still worked, in Production and the other developer sandbox, but not the full sandbox which was recently refreshed. 

This is one of the failures i get when adding or editing an opportunity:
"Apex trigger UpdateOpportunityProduct caused an unexpected exception, contact your administrator: UpdateOpportunityProduct: execution of BeforeUpdate caused by: line 5, column 21: trigger body is invalid and failed recompilation: Variable does not exist: pricebookentryid"

and the code:
trigger UpdateOpportunityProduct on OpportunityLineItem (before insert, before update) {
	    Set<Id> pbeIds = new Set<Id>();
	    for (OpportunityLineItem oli : Trigger.new) 
	        pbeIds.add(oli.pricebookentryid);
	    Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([select Product2.Product_Type__c, Product2.Product_Category__c, Product2.ProductCode, Product2.Assessment__c, Product2.PD_Complimentary_Group_Type__c from PricebookEntry where id in :pbeIds]);
	    for (OpportunityLineItem oli: Trigger.new) {
	        Product2 product = entries.get(oli.PricebookEntryId).Product2;
	        oli.Product_Type__c = product.Product_Type__c;
	    }  
}

Already reach out to salesforce and closed my ticketet saying it's "Internal Server Error", let me know what you guys think?


I found this trigger and it seems that one of the past developer is doing an update  of an opportunity within the trigger instead with the class.

From what I understood, that the class will still be executing eventhough after the record page has been updated and reloaded for the end-user? Never experience this before, how about anyone here?

trigger Opp on Opportunity (after update) {
    for (Integer i = 0; i < Trigger.old.size(); i++) {
        Opportunity old = Trigger.old[i];
        Opportunity nw = Trigger.new[i];
        Boolean man = false;
      
        if ((nw.Probability == 100) && (old.Probability != nw.Probability)) {
      
            oppClose.createCase(nw.Id, man);
            //Clone statuses indicate different follow-up actions for people.
            if (nw.Clone_Status__c != 'Completed' && nw.Clone_Status__c != 'Non-renewable' && nw.Clone_Status__c != 'Exception') {
            oppClose.cloneOpp(nw.Id);
          
            /*Clone Status field is updated from the trigger instead of the the class. The class runs asynchronsously (ie. in the future)
            * so the results do not show up immediatley in the Opp after closing it won and returning to the saved record.
            * By updating the field in the trigger a flag is set to alert the user and to prevent a subsequent update from
            * triggering the class again if the async execution is delayed.
            */
            Opportunity opp = new Opportunity(
            Id = nw.Id,
            Clone_Status__c = 'Completed');
            update opp;
            }
        }
    }
  • January 15, 2014
  • Like
  • 0
I have this VF page, with a contact look up field when selected it pre-populate shipping address fields based on contact select. For this example I have two "John Smith" contact records. 
If I were to either enter or copy the entire name I get this that pop ups which is expect: before enter to select

When I hit enter this happens: User-added image  

The my recent items stay there, I can't click on it nor can I even click on that drop-down menu.
This happens all the time with Firefox, sometimes with Chrome, and never with IE.
Does this ever happens to anyone before? I am using actionRegion in very common way that is pre-populate fields based on look up field selected.

Below is the VF code:
<apex:actionRegion >  
                <apex:pageBlockSection id="Shipto" title="2) Shipment Details" collapsible="false">     
                    <apex:inputField value="{!case.ShipToContact__c}" required="true">
                        <apex:actionSupport event="onchange" action="{!ShipToPopulated}" rerender="Shipto, msgs"/>
                    </apex:inputField>   
                    <apex:outputField value="{!case.Ship_To_Account__c}"/> 
                    <apex:inputField value="{!case.ShippingStreet__c}"/> 
                    <apex:inputField value="{!case.ShippingCity__c}"/> 
                    <apex:inputField value="{!case.ShippingState1__c}"/> 
                    <apex:inputField value="{!case.ShippingPostalCode__c}"/>                                              
                </apex:pageBlockSection>
            </apex:actionRegion>


 
  • December 22, 2014
  • Like
  • 0
I have a public site page form that creates a case and assigns it to the owner that is query within Apex. Since, its is a public site it doesn't query anything from the user object.

Using "Site.getAdminId()" doesn't work in my case, since I am the site administrator that is not what I want.

16:09:31.169 (169671978)|SOQL_EXECUTE_BEGIN|[119]|Aggregations:0|SELECT Id FROM User WHERE Name = 'Salesforce Administrators' LIMIT 1
16:09:31.189 (189902826)|SOQL_EXECUTE_END|[119]|Rows:0
16:09:31.190 (190228383)|SYSTEM_MODE_EXIT|false
16:09:31.190 (190383656)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject


  • September 09, 2014
  • Like
  • 0
I borrow  a good part of michalforce receipe (http://www.michaelforce.org/recipeView?id=a0G30000006eVxVEAU) and used this shopping cart code work with creating a case.

So whenever, I added a new product to the shopping cart, the quantity doesn't get saved. The quantity is stored in a wrapper class, and if system.debug upon saving it shows that PricebookEntry object and quantity is in the "shoppingCart2" wrapper list, somehow {!s.productQuantity} in VF isn't being pulled.?

Here is the entire Apex:
public with sharing class InternalFurfillment2 {

    public String searchString {get;set;}

    private List<PriceBookWrapper> forDeletion2 = new List<PriceBookWrapper>();
    public List<PriceBookWrapper> shoppingCart2 {get;set;}
    
    public priceBookEntry[] AvailableProducts {get;set;}
    public String toSelect {get; set;}
    public String toUnselect {get; set;}
    public Boolean overLimit {get;set;}
    
    public string priceBookName = 'Internal Price Book';
    
    private ApexPages.StandardController stdController;    
    private Case caseObject;
      
    public InternalFurfillment2(ApexPages.StandardController controller) {
        this.caseObject = (Case) controller.getRecord();  
        shoppingCart2 = new List<PriceBookWrapper>();

        updateAvailableList();       
    }

    public void updateAvailableList() {
        
        // We dynamically build a query string and exclude items already in the shopping cart
        String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Family, Product2.IsActive, Product2.Description, UnitPrice, Product2.Vendor__c from PricebookEntry where IsActive=true and PricebookEntry.Pricebook2.Name = \'' + priceBookName + '\'';
        system.debug('qString begin==>' + qString);
        // note that we are looking for the search string entered by the user in the name OR description
        // modify this to search other fields if desired
        if(searchString!=null){
            qString+= ' and (Product2.Name like \'%' + searchString + '%\' or Product2.Description like \'%' + searchString + '%\')';
        }
        
        Set<Id> selectedEntries = new Set<Id>();
        
        for(PriceBookWrapper d : shoppingCart2){
            system.debug('d==>' + d);
            selectedEntries.add(d.pbeEntry.Id);
        }
        system.debug('selectedEntries==>' + selectedEntries);
               
        if(selectedEntries.size()>0){
            String tempFilter = ' and Id not in (';
            for(Id i : selectedEntries){
                tempFilter+= '\'' + (String)i + '\',';
            }
            String extraFilter = tempFilter.substring(0,tempFilter.length()-1);
            extraFilter+= ')';
            
            qString+= extraFilter;
        }
        
        qString+= ' order by Product2.Name';
        qString+= ' limit 101';
        
        system.debug('qString:' +qString);        
        AvailableProducts = database.query(qString);
        
        // We only display up to 100 results... if there are more than we let the user know (see vf page)
        if(AvailableProducts.size()==101){
            AvailableProducts.remove(100);
            overLimit = true;
        }
        else{
            overLimit=false;
        }
    }
    
    public void addToShoppingCart(){
        system.debug('AvailableProducts==>' + AvailableProducts);
        system.debug('shopping cart outside top==>' + ShoppingCart2); 
        // This function runs when a user hits "select" button next to a product    
        for(PricebookEntry d : AvailableProducts){
            if((String)d.Id==toSelect){
                shoppingCart2.add(new PriceBookWrapper(d,0)); system.debug('shopping cart inside==>' + ShoppingCart2);
                break;
            }
        }system.debug('shopping cart outside==>' + ShoppingCart2);       
        updateAvailableList();  
    }
    

    public PageReference removeFromShoppingCart(){    
        // This function runs when a user hits "remove" on an item in the "Selected Products" section            Integer count = 0;    
        for(PriceBookWrapper d : shoppingCart2){
            if((String)d.pbeEntry.Id==toUnselect){            
                if(d.pbeEntry.Id!=null)
                    forDeletion2.add(d);            
                shoppingCart2.remove(count);
                break;
            }
            count++;
        }        
        updateAvailableList();       
        return null;
    }
    
    public PageReference onSave(){        
        system.debug('shoppingCart2 submit==>' + shoppingCart2);
               return null;
    }
         
     public class PriceBookWrapper{  
         public Integer productQuantity {get;set;}  
         public PriceBookEntry pbeEntry {get;set;}  
         
         public PriceBookWrapper(PriceBookEntry pbeEntry, Integer productQuantity){  
             this.pbeEntry = pbeEntry;  
             this.productQuantity = productQuantity; 
         }      
    }  
}


The portion of VF that where quantity should be displaying:
..	
<apex:pageBlock title="My Content">	
		<apex:outputPanel id="mainBody">
        
<!-- this is the upper table... a.k.a. the "Shopping Cart"-->
            <!-- notice we use a lot of $ObjectType merge fields... I did that because if you have changed the labels of fields or objects it will reflect your own lingo -->
            <apex:pageBlockSection title="{!$ObjectType.Product2.LabelPlural} Selection" id="selected" columns="1"> 
                <apex:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                <apex:pageblockTable value="{!shoppingCart2}" var="s">
                
                    <apex:column >
                        <apex:commandLink value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true">
                            <!-- this param is how we send an argument to the controller, so it knows which row we clicked 'remove' on -->
                            <apex:param value="{!s.pbeEntry.Id}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.pbeEntry.Product2.Name}"/>
                    
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputText value="{!s.productQuantity}" style="width:70px" required="true" onkeyup="refreshTotals();"/>
                    </apex:column>
                        <!--   -->
             
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description.Label}">
                        <apex:outputField value="{!s.pbeEntry.Product2.Family}"/>    
                    </apex:column>
                   
                </apex:pageblockTable>
         </apex:pageBlock>
...


This is the entire VF page:

<apex:form>
	<apex:pageBlock title="My Content">	
		<apex:outputPanel id="mainBody">
			<apex:pageBlockSection title="{!$ObjectType.Product2.LabelPlural} Selection" id="selected" columns="1"> 
                <apex:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                <apex:pageblockTable value="{!shoppingCart2}" var="s">
                
                    <apex:column >
                        <apex:commandLink value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true">
                            <!-- this param is how we send an argument to the controller, so it knows which row we clicked 'remove' on -->
                            <apex:param value="{!s.pbeEntry.Id}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.pbeEntry.Product2.Name}"/>
                    
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputText value="{!s.productQuantity}" style="width:70px" required="true" onkeyup="refreshTotals();"/>
                    </apex:column>
                        <!--   -->
             
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description.Label}">
                        <apex:outputField value="{!s.pbeEntry.Product2.Family}"/>    
                    </apex:column>
                   
        </apex:pageblockTable>
    </apex:pageBlock>
    
		<!--this is the lower table: search bar and search results-->
		<apex:pageBlock >          
			<apex:outputPanel styleClass="search">
				Search for {!$ObjectType.Product2.LabelPlural}:
			</apex:outputPanel>

			<apex:actionRegion renderRegionOnly="false" immediate="true">
			
				<apex:actionFunction name="fetchResults" action="{!updateAvailableList}" reRender="searchResults" status="searchStatus"/>
				
				<!-- here we invoke the scripting to get out fancy 'no button' search bar to work -->
				<apex:inputText value="{!searchString}" onkeydown="if(event.keyCode==13){this.blur();}else{resetTimer();}" style="width:300px"/>
				&nbsp;&nbsp;
				<i>
					<!-- actionStatus component makes it easy to let the user know when a search is underway -->
					<apex:actionStatus id="searchStatus" startText="searching..." stopText=" "/>
				</i>
				
			</apex:actionRegion>
		
			<br/>
			<br/>
		
			<apex:outputPanel id="searchResults">
			
				<apex:pageBlockTable value="{!AvailableProducts}" var="a">
				
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Name.Label}" value="{!a.Product2.Name}" />
					
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Family.Label}" value="{!a.Product2.Family}"/>
					
					<apex:column headerValue="{!$ObjectType.Product2.Fields.Description.Label}" value="{!a.Product2.Description}"/>
					
					<apex:column >
						<!-- command button in a column... neato -->
						<apex:commandButton value="Select" action="{!addToShoppingCart}" reRender="selected,searchResults" immediate="true">
							<!-- again we use apex:param to be able to tell the controller which row we are working with -->
							<apex:param value="{!a.Id}" assignTo="{!toSelect}" name="toSelect"/>
						</apex:commandButton>
					</apex:column>
					
				</apex:pageBlockTable>
				
				<!-- We put up a warning if results exceed 100 rows -->
				<apex:outputPanel styleClass="fyi" rendered="{!overLimit}">
					<br/>
					Your search returned over 100 results, use a more specific search string if you do not see the desired {!$ObjectType.Product2.Label}.
					<br/>
				</apex:outputPanel>
				
				</apex:outputPanel>
				</apex:pageBlock>
			</apex:pageBlockSection>
		</apex:outputPanel>

		<apex:pageBlockSectioncolumns="1">
				   <apex:outputPanel layout="block" style="align: center">
			   <apex:commandButton action="{!onSave}" value="Save"/>
			</apex:outputPanel>

		</apex:pageBlockSection> 
		</apex:pageBlock>
    </apex:form>

</apex:page>





  • August 27, 2014
  • Like
  • 0
I made sure that under develop -> case -> custom settings > Notify Case Owners when Case Ownership Changes is unchecked.

When I change owner through a before update trigger it ends up sending out an email to the new owner. Any thoughts?

trigger CaseTrigger on Case (before update) {
	
	for(Case c : trigger.new) {
		c.owner = xxx;
	}

}




  • August 07, 2014
  • Like
  • 0
We have serveral triggersdating back from the days before my time, many have been failing and with similar errors.
They all  has always worked and still worked, in Production and the other developer sandbox, but not the full sandbox which was recently refreshed. 

This is one of the failures i get when adding or editing an opportunity:
"Apex trigger UpdateOpportunityProduct caused an unexpected exception, contact your administrator: UpdateOpportunityProduct: execution of BeforeUpdate caused by: line 5, column 21: trigger body is invalid and failed recompilation: Variable does not exist: pricebookentryid"

and the code:
trigger UpdateOpportunityProduct on OpportunityLineItem (before insert, before update) {
	    Set<Id> pbeIds = new Set<Id>();
	    for (OpportunityLineItem oli : Trigger.new) 
	        pbeIds.add(oli.pricebookentryid);
	    Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([select Product2.Product_Type__c, Product2.Product_Category__c, Product2.ProductCode, Product2.Assessment__c, Product2.PD_Complimentary_Group_Type__c from PricebookEntry where id in :pbeIds]);
	    for (OpportunityLineItem oli: Trigger.new) {
	        Product2 product = entries.get(oli.PricebookEntryId).Product2;
	        oli.Product_Type__c = product.Product_Type__c;
	    }  
}

Already reach out to salesforce and closed my ticketet saying it's "Internal Server Error", let me know what you guys think?


I found this trigger and it seems that one of the past developer is doing an update  of an opportunity within the trigger instead with the class.

From what I understood, that the class will still be executing eventhough after the record page has been updated and reloaded for the end-user? Never experience this before, how about anyone here?

trigger Opp on Opportunity (after update) {
    for (Integer i = 0; i < Trigger.old.size(); i++) {
        Opportunity old = Trigger.old[i];
        Opportunity nw = Trigger.new[i];
        Boolean man = false;
      
        if ((nw.Probability == 100) && (old.Probability != nw.Probability)) {
      
            oppClose.createCase(nw.Id, man);
            //Clone statuses indicate different follow-up actions for people.
            if (nw.Clone_Status__c != 'Completed' && nw.Clone_Status__c != 'Non-renewable' && nw.Clone_Status__c != 'Exception') {
            oppClose.cloneOpp(nw.Id);
          
            /*Clone Status field is updated from the trigger instead of the the class. The class runs asynchronsously (ie. in the future)
            * so the results do not show up immediatley in the Opp after closing it won and returning to the saved record.
            * By updating the field in the trigger a flag is set to alert the user and to prevent a subsequent update from
            * triggering the class again if the async execution is delayed.
            */
            Opportunity opp = new Opportunity(
            Id = nw.Id,
            Clone_Status__c = 'Completed');
            update opp;
            }
        }
    }
  • January 15, 2014
  • Like
  • 0