• Bruno Lima
  • NEWBIE
  • 0 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 0
    Replies
Hi guys!

I have a test class that I'm having a hard time to get it done and work. If any of you could help me, would be much appreciated.

This is the 1st Class:
public with sharing class opportunityProductEntryExtension {

    public Opportunity theOpp {get;set;}
    public String searchString {get;set;}
    public String searchstring2 {get;set;} 
    
    public opportunityLineItem[] shoppingCart {get;set;}
    public priceBookEntry[] AvailableProducts {get;set;}
    public Pricebook2 theBook {get;set;}   
    public string recordtypeidname {get;set;}
    public boolean checked {get;set;}

    public String Sections{get; set;}
            
    public String toSelect {get; set;}
    public String toUnselect {get; set;}
    public Decimal Total {get;set;}
    
    public Boolean overLimit {get;set;}
    public Boolean multipleCurrencies {get; set;}
    public List<SelectOption> getsectionnames {get;set;}
    
    private Boolean forcePricebookSelection = false;
    
    private opportunityLineItem[] forDeletion = new opportunityLineItem[]{};


    public opportunityProductEntryExtension(ApexPages.StandardController controller) {

        // Need to know if org has multiple currencies enabled
        multipleCurrencies = UserInfo.isMultiCurrencyOrganization();

        // Get information about the Opportunity being worked on
        if(multipleCurrencies)
            theOpp = database.query('select Id, Pricebook2Id, Pricebook2.Name, CurrencyIsoCode from Opportunity where Id = \'' + controller.getRecord().Id + '\' limit 1');
        else
            theOpp = [select Id, Pricebook2Id,AccountId,OwnerId, CloseDate, PriceBook2.Name from Opportunity where Id = :controller.getRecord().Id limit 1];
        
        //assegna il valore del recordtype alla variabile
       // recordtypeidname = theOpp.RecordType.name;
       // 
        // If products were previously selected need to put them in the "selected products" section to start with
        shoppingCart = [select Id, quantity,Family__c, unitprice,Area__c,TotalPrice,Refund__c,Supplier__c, ServiceDate,Change_Order__c, Discount,Description, Description__c, PriceBookEntryId, PriceBookEntry.Name, PriceBookEntry.IsActive, PriceBookEntry.Product2Id, PriceBookEntry.Product2.Name, PriceBookEntry.PriceBook2Id from opportunityLineItem where (OpportunityId=:theOpp.Id) ];
       
        // Check if Opp has a pricebook associated yet
        if(theOpp.Pricebook2Id == null){
            Pricebook2[] activepbs = [select Id, Name from Pricebook2 where isActive = true limit 2];
            if(activepbs.size() == 2){
                forcePricebookSelection = true;
                theBook = new Pricebook2();
            }
            else{
                theBook = activepbs[0];
            }
        }
        else{
            theBook = theOpp.Pricebook2;
        }
        
        if(!forcePricebookSelection)
            updateAvailableList();
    }
    
    // this is the 'action' method on the page
    public PageReference priceBookCheck(){
    
        // if the user needs to select a pricebook before we proceed we send them to standard pricebook selection screen
        if(forcePricebookSelection){        
            return changePricebook();
        }
        else{
        
            //if there is only one active pricebook we go with it and save the opp
            if(theOpp.pricebook2Id != theBook.Id){
                try{
                    theOpp.Pricebook2Id = theBook.Id;
                    update(theOpp);
                }
                catch(Exception e){
                    ApexPages.addMessages(e);
                }
            }
            
            return null;
        }
    }
       
    public String getChosenCurrency(){
    
        if(multipleCurrencies)
            return (String)theOpp.get('CurrencyIsoCode');
        else
            return '';
    }

    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 from PricebookEntry where IsActive=true and Pricebook2Id = \'' + theBook.Id + '\'';
        
        String searchstring3 = Sections;
        if(multipleCurrencies)
            qstring += ' and CurrencyIsoCode = \'' + theOpp.get('currencyIsoCode') + '\'';
        
       
        // 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 + '%\')';
        }
        if(searchString3!=null) if (searchString3!='All'){
            qString+= ' and (Product2.Name like \'%' + searchString3 + '%\' or Product2.Description like \'%' + searchString3 + '%\')';
        }
        
        Set<Id> selectedEntries = new Set<Id>();
        for(opportunityLineItem d:shoppingCart){
            selectedEntries.add(d.PricebookEntryId);
        }
        
        /*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(){
    
        // This function runs when a user hits "select" button next to a product
    
        for(PricebookEntry d : AvailableProducts){
            if((String)d.Id==toSelect){
                shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d, unitprice=d.unitprice, PriceBookEntryId=d.Id));
                break;
            }
        }
        
        updateAvailableList();  
    }
    
    public void addAllToShoppingCart(){
    
        // This function runs when a user hits "select" button next to a product
    
        for(PricebookEntry d : AvailableProducts){
            shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d,  PriceBookEntryId=d.Id));
           }
        
        
        updateAvailableList();  
    }
    

    public PageReference removeFromShoppingCart(){
    
        // This function runs when a user hits "remove" on an item in the "Selected Products" section
    
        Integer count = 0;
    
        for(opportunityLineItem d : shoppingCart){
            if((String)d.PriceBookEntryId==toUnselect){
            
                if(d.Id!=null)
                    forDeletion.add(d);
            
                shoppingCart.remove(count);
                break;
            }
            count++;
        }
        
        updateAvailableList();
        
        return null;
    }
    
    public PageReference onSave(){
    
    
        // If previously selected products are now removed, we need to delete them
        if(forDeletion.size()>0)
            delete(forDeletion);
            upsert(theOpp);
    
        // Previously selected products may have new quantities and amounts, and we may have new products listed, so we use upsert here
        try{
            if(shoppingCart.size()>0)
                upsert(shoppingCart);
                upsert(theOpp);
        }
        catch(Exception e){
            ApexPages.addMessages(e);
            return null;
        }  
           
        // After save return the user to the Opportunity
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
    }
    
    public PageReference onCancel(){

        // If user hits cancel we commit no changes and return them to the Opportunity   
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
    }
    
    public PageReference changePricebook(){
    
        // This simply returns a PageReference to the standard Pricebook selection screen
        // Note that is uses retURL parameter to make sure the user is sent back after they choose
    
        PageReference ref = new PageReference('/oppitm/choosepricebook.jsp');
        ref.getParameters().put('id',theOpp.Id);
        ref.getParameters().put('retURL','/apex/opportunityProductEntry?id=' + theOpp.Id);
        
        return ref;
    }
   
    public List<SelectOption> getsectionnames(){ 
         List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Baseboards','Baseboards'));
        options.add(new SelectOption('Bathroom','Bathroom'));
        options.add(new SelectOption('Bath Tubs','Bath Tubs'));
        options.add(new SelectOption('Cabinets','Cabinets'));
        options.add(new SelectOption('Counter Tops','Counter Tops'));
        options.add(new SelectOption('Demolition','Demolition'));
        options.add(new SelectOption('Doors','Doors'));
        options.add(new SelectOption('Drywall','Drywall'));
        options.add(new SelectOption('Electrical','Electrical'));
        options.add(new SelectOption('Faucets','Faucets'));
        options.add(new SelectOption('Flooring','Flooring'));
        options.add(new SelectOption('HVAC','HVAC'));
        options.add(new SelectOption('Labour','Labour'));
        options.add(new SelectOption('Paneling / Moulds','Paneling / Moulds'));
        options.add(new SelectOption('Plumbing','Plumbing'));
        options.add(new SelectOption('Showers','Showers'));
        options.add(new SelectOption('Sinks','Sinks'));
        options.add(new SelectOption('Tiles/ Tiling','Tiles/ Tiling'));
        options.add(new SelectOption('Hardware','Hardware'));
       // List<Sections_Picklist__c> Sectionlist = new List<Sections_Picklist__c>();  
        /*Sectionlist = [Select  Family FROM Product2 ORDER BY name];
          for (Integer j=0;j<sectionlist.size();j++)  { 
                 options.add(new SelectOption(sectionlist[j].Family,sectionlist[j].Family));  
                 }*/
           return options;
      }
    
    public with sharing class opportunityProductRedirectExtension {

    Id oppId;

    // we are extending the OpportunityLineItem controller, so we query to get the parent OpportunityId
    public opportunityProductRedirectExtension(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/opportunityProductEntry?id=' + oppId);
    }

}
    
}
The second class:
 
public with sharing class opportunityProductRedirectExtension {

    public opportunityProductRedirectExtension(ApexPages.StandardController controller) {

    }

}

Visual force page:
 
<apex:page standardController="Opportunity" extensions="opportunityProductEntryExtension" sidebar="false" action="{!priceBookCheck}" lightningStylesheets="true">

    <apex:sectionHeader Title="Manage {!$ObjectType.Product2.LabelPlural}" subtitle="{!opportunity.Name}"/>
    <apex:messages style="color:red"/>
<!--apex:outputText value="{!opportunity.RecordType.Name}"/-->
        
    <style> 
        .search{
            font-size:14pt;
            margin-right: 20px;    
        }
        .fyi{
            color:red;
            font-style:italic;
        }
        .label{ 
            margin-right:10px;
            font-weight:bold;
        }
    </style>
    
    <script type='text/javascript'>
    
        // This script assists the search bar functionality
        // It will execute a search only after the user has stopped typing for more than 1 second
        // To raise the time between when the user stops typing and the search, edit the following variable:
        
        var waitTime = 1;
        
    
        var countDown = waitTime+1;
        var started = false;
        
        function resetTimer(){
        
            countDown=waitTime+1;
            
            if(started==false){
                started=true;
                runCountDown();
            }
        }
        
        function runCountDown(){
        
            countDown--;
            
            if(countDown<=0){
                fetchResults();
                started=false;
            }
            else{
                window.setTimeout(runCountDown,1000);
            }
        }
    
    </script>
   
  
    <apex:form >
    
        <apex:outputPanel id="mainBody">
        
            <!--apex:outputLabel styleClass="label">PriceBook: </apex:outputLabel>
            <apex:outputText value="{!theBook.Name}"/>&nbsp;
             <apex:commandLink action="{!changePricebook}" value="change" immediate="true"/-->
            <br/>
            <!-- not everyone is using multi-currency, so this section may or may not show -->
            <!--apex:outputPanel rendered="{!multipleCurrencies}"-->
            <!--
                <apex:outputLabel styleClass="label">Currency: </apex:outputLabel>
                <apex:outputText value="{!chosenCurrency}"/>
                <br/>
            </apex:outputPanel>
            <br/>
            
<!-- 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:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                       
                <apex:pageblockTable value="{!shoppingCart}" 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.PriceBookEntryId}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    <!--apex:column width="25px">
                    <apex:inputcheckbox value="{!checked}"/>
                    </apex:column> -->
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.PriceBookEntry.Product2.Name}"/>
                    
                  <!--  <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Profile__c.Label}" rendered="{!opportunity.Market__c != 'MTS DATA'}">
                                       
                        <apex:inputField value="{!s.Profile_CAT__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Cash Markets'}" />
                        <!-- apex:inputField value="{!s.Profile_CAT__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Live'}" /
                        <apex:inputField value="{!s.Profile_MMF__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Repo Markets'}" />
                        <apex:inputField value="{!s.Profile_BV__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Bondvision'}" />    
                        <apex:inputField value="{!s.Profile_ACM__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS ACM'}" />    
                     </apex:column> -->
                    
                      <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputField value="{!s.Quantity}" style="width:70px" required="true" onkeyup="refreshTotals();" />
                    </apex:column>

                      <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.UnitPrice.Label}" >
                        <apex:inputField value="{!s.UnitPrice}" style="width:70px" required="true" onkeyup="refreshTotals();" />
                    </apex:column>
                                                               
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description__c.Label}">
                        <apex:inputField value="{!s.Description__c}" required="false"/>
                    </apex:column>
                    
                </apex:pageblockTable>
            
            
                <apex:pageBlockButtons >
                    <apex:commandButton action="{!onSave}" value="Save"/>
                    <apex:commandButton action="{!onCancel}" value="Cancel" immediate="true"/>
                    <!--apex:commandButton action="{!onadd}" value="Add Selected"/-->
                </apex:pageBlockButtons>
            
            </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" />
                         <apex:actionFunction name="fetchResults1" action="{!updateAvailableList}" reRender="searchResults" status="searchStatus"/>

               <!-- <apex:outputPanel styleClass="search" >
                    Area
                </apex:outputPanel>-->

                         
                         <apex:outputlabel value="Sections" for="values"/>
                         <apex:selectList value="{!Sections}" size="1" id="values">
                             <apex:actionSupport event="onchange" action="{!updateAvailableList}" reRender="searchResults" />
                             <apex:selectOptions value="{!Sectionnames}"/>     
                          </apex:selectList>
                <apex:outputPanel styleClass="search">

                </apex:outputPanel> 
                          
                          <apex:commandButton action="{!addAllToShoppingCart}" value="Add All Products" reRender="selected,searchResults" immediate="true"/>

                    &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/>
            
                <apex:outputPanel id="searchResults">
                
                    <apex:pageBlockTable value="{!AvailableProducts}" var="a">
                    
                    <apex:column width="25px"> 
                    <apex:inputcheckbox value="{!checked}"/>
                    </apex:column> 
                    
                        <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:outputPanel>
    </apex:form>
    </apex:page>

Test class:
 
@istest
private class opportunityProductEntryTests{

    static testMethod void theTests(){

   //     TestUtilities tu = TestUtilities.generateTest();
// this is an external class that will generate a number of records I will query below.
// I suggest creating a TestUtility class to be called by your test class instead of creating the 
// records in each test class.
// This to save time, code and providing a clear code organization.

        // Find standard pricebook ID
        Id pricebookId = Test.getStandardPricebookId();

       
        
        //Create new product
        Product2 p = new Product2(Name='test', IsActive = true, Family = 'Plumbing');
        insert p;
        
         //Creating pricebook entry
        PricebookEntry standardPrice = new PricebookEntry(
            Pricebook2Id = pricebookId, Product2Id = p.Id,
            UnitPrice = 10000, IsActive = true);
        insert standardPrice;
        
        //Create new Account
        Account acc = new Account (Name='Focus', ZuminLocation__c='NW Mississauga');
        insert acc;
        
        //Create New Opportunity
       Opportunity opp = new Opportunity (Name = 'test',Pricebook2Id= pricebookId,  AccountId = acc.id, StageName ='Closed Won', CloseDate = system.today());
        insert opp;
        
        //Create Opp product 
        OpportunityLineItem opp1 = new OpportunityLineItem(OpportunityId =opp.id, Product2Id = p.id, UnitPrice =0, Quantity = 1);
        insert opp1;
        
        // Create new Opp Line Item
        OpportunityLineItem oli = [select Id, PricebookEntryId, PricebookEntry.Pricebook2Id, PricebookEntry.Name, PriceBookEntry.Product2Id, OpportunityId, Opportunity.AccountId FROM OpportunityLineItem ];
        system.debug('value dell id :' + oli.id);      
                
        ////////////////////////////////////////
        //  test opportunityProductEntry
        ////////////////////////////////////////
        
        // load the page   
        Test.StartTest();
      
        PageReference pageRef = Page.NewProducts;
        pageRef.getParameters().put('Id',opp.Id);
        Test.setCurrentPageReference(pageRef);
        
      //  Apexpages.StandardController stdController = new Apexpages.StandardController(opp1);
      //  opportunityProductEntryExtension controller = new opportunityProductEntryExtension(stdController);
        
        ApexPages.StandardController sc = new ApexPages.standardController(new Opportunity());
// create an instance of the controller
opportunityProductEntryExtension co = new opportunityProductEntryExtension(sc);
        
        String options = 'Plumbing';
        sc.save();
        sc.edit();
        sc.view();
        sc.cancel();
        sc.getId();
        sc.getRecord();
        
       Test.StopTest();
        
        //
        // load the extension
      //  opportunityProductEntryExtension oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(opp1));
        
       /* // test 'getChosenCurrency' method
        if(UserInfo.isMultiCurrencyOrganization())
            System.assert(oPEE.getChosenCurrency()!='');
        else
            System.assertEquals(oPEE.getChosenCurrency(),'');


        ////////////////////////////////////////
        //  test redirect page
        ////////////////////////////////////////
        
   

      opportunityProductRedirectExtension(new ApexPages.StandardController(oli2[0]));
     
    }
}


 
Hye everyone!

I don't know if it would be possible to create a quote wihtout been attached to an opportunity. Does anyone know any workaround?
Hi evryone,

does anyone know if it is possible to track who was the last user that changed the Actual approver?

Any way to know who could reassigned a new user in a custom object.

Thanks in advance
Hi everyone,

is there a way to filter emails, in activity capture, that onlycontain information related to the Opportunity. Let me show scenario:

1. I have one contact which is related to more than one (Opp A and Opp B) Opp, but I want Activity capture to show on Opp A just those emails that I sent to the contact related to the Opp A and the same for the Opp B.

Also, I thought that using the Insights would help me filter it, but won't help me filter which email was from Opp A and Opp B. Just filter those ones that, somehow, was related to an Opp.

Do you have a solution or workaround for that? Any way that I can use formulas to capture the info that I want?
Hello everyone !

I have a question based on how I can define my PDF's name.

So, I'm not using any Content Type or renderAs in my VF page but I would like to know how I can define it in my controller.

I tryed to use input and then "attachment" but I'm always getting errors when I try to load the PDF generated.

Can someone help me out?