• Ty Whitfield
  • NEWBIE
  • 105 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 31
    Questions
  • 39
    Replies
I've tested my Lightning Component and it worked as expected and see Contacts for displayed in my component.  Another user looking at the same account sees "There are no Team Lead or Support contacts"
public  class accController {
    @AuraEnabled
    public static list<Contact> getTrainingSubscription(Id recordId)
    {
        List<Contact> Conlist = [Select Id, Training_Subscription_User__c, Name, Email, Contact_Status__c, Last_Training_Login_Date__c from Contact where AccountId= :recordId and Training_Subscription_User__c = true ORDER By Contact_Status__c];
        return Conlist;
    }

    @AuraEnabled
    public static list<Contact> getSupportUsers(Id recordId)
    {
        List<Contact> Conlist =  [SELECT Id, Email,My_ASCI_Role__c,Name,  Experience__c FROM Contact WHERE  AccountId=:recordId AND (My_ASCI_Role__c = 'Team Lead' OR My_ASCI_Role__c = 'Support User') order by My_ASCI_Role__c desc];
        return Conlist;
    }

     @AuraEnabled
    public static decimal getAverageExperience(Id recordId)
    {      

      
        List<Contact> acctContacts = [SELECT Id, Email,My_ASCI_Role__c,Name,  Experience__c FROM Contact WHERE  AccountId=:recordId AND (My_ASCI_Role__c = 'Team Lead' OR My_ASCI_Role__c = 'Support User') order by My_ASCI_Role__c desc];
              integer j = 0; 
        decimal avgExperience = 0;
            while(j <  acctContacts.size())
            {
              avgExperience = avgExperience + acctContacts[j].Experience__c;
                   
                j++;
            } 
        
        if(acctContacts.size() != null && acctContacts.size() != 0)
        {
            avgExperience = (avgExperience / acctContacts.size());
        }
        return avgExperience;
    }

     @AuraEnabled
    public static Integer getSubPurchased(Id recordId)
    {    
       List<Account>  acct = [Select Id, Training_Subscription_Seats_Available__c FROM Account where Id= :recordId];  

      return   Integer.valueOf(acct[0].Training_Subscription_Seats_Available__c);
      
    }

     @AuraEnabled
    public static Integer getSubLeft(Id recordId)
    {      
        List<Account>  acct = [Select Id, Training_Subscription_Seats_Available__c FROM Account where Id= :recordId];  
        List <Contact>  acctContacts = [Select Id, Training_Subscription_User__c, Name, Email, Contact_Status__c, Last_Training_Login_Date__c from Contact where AccountId= :recordId and Training_Subscription_User__c = true ORDER By Contact_Status__c];
      
      return  Integer.valueOf(acct[0].Training_Subscription_Seats_Available__c) - acctContacts.size();
    }




     
       
}
 
<aura:component controller="accController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <!--testComponentTrngSubSupportUsers-->
     <aura:attribute name="recordId" type="Id" access="global" />
    <aura:attribute name="ContactList" type="Contact[]" access="global" />
    <aura:attribute name="avg" type="Decimal" access="global" />
     <aura:handler name="init" value="{!this}" action="{!c.myAction}" access="global" />
     <lightning:card iconName="standard:case_wrap_up" title="Team Lead and Support User List">
     <aura:if isTrue="{!not(empty(v.ContactList))}">
         <center>Average Experience: <lightning:formattedNumber value="{!v.avg}"/> days</center>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
         <thead>
            <tr class="slds-text-title">
                <th  style="padding-left:10px;background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Name">Name</div>
                </th>
                <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Email">Email</div>
                </th>
                 <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                     <div class="slds-truncate" title="Experience">Experience</div>
                </th>
                <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Role">My ASCI<br/>Role</div>
                </th>
            </tr>
        </thead>
        <tbody>
   
    <aura:iteration   items="{!v.ContactList}" var="con">
        <tr>
                    <td data-label="Name" style="padding-left:10px">
                        
                      
                         <div class="slds-truncate" title="">
                             <lightning:formattedUrl  value="{! '/' + con.Id}" label="{!con.Name}"  target="_blank" />
                             </div>
                    </td>
                    <td data-label="Email">
                        <div class="slds-truncate" title="">
                             <lightning:formattedUrl  value="{! '/' + con.Id}" label="{!con.Email}"  target="_blank" /></div>
                    </td>
             <td data-label="Experience">
                        <div class="slds-truncate" title=""><lightning:formattedNumber value="{!con.Experience__c}"/> days</div>
                    </td>
                    <td data-label="Role">
                        <div class="slds-truncate" title="">{!con.My_ASCI_Role__c}</div>
                    </td>
                </tr>
        
       
    </aura:iteration>
        </tbody>
         </table>
	  <aura:set attribute="else">
                <div Style="text-align : center">  There are no Team Lead or Support contacts </div>
            </aura:set>
        </aura:if>
    </lightning:card>
	
</aura:component>
 
({
 myAction : function(component, event, helper) 
    {
        var ConList = component.get("c.getSupportUsers");
        ConList.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        ConList.setCallback(this, function(data) 
                           {
                               component.set("v.ContactList", data.getReturnValue());
                           });
        $A.enqueueAction(ConList);
        
        
        var avg = component.get("c.getAverageExperience");
        avg.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        avg.setCallback(this, function(data) 
                           {
                               component.set("v.avg", data.getReturnValue());
                           });
        $A.enqueueAction(avg);
        
        
 }
})

I've tried the code below (removed some items for confidentiality) but I receive the "made it to the query locator" debug message but never receive the "made it to the execute" debug.  I'm calling it by entering

batchGenerateAssets be = new batchGenerateAssets();
database.executeBatch(be);

in Execute Anonymous Window of the Developer Console

 

What am I doing wrong?

global class batchGenerateAssets implements Database.Batchable<sObject>, Database.AllowsCallouts{

 public String query = 'Select Id, PakSize__c, ProductFamily, UsageEndDate, Product2Id  FROM Asset WHERE SerialNumber = \'**Generate**\' ';

global Database.QueryLocator start(Database.BatchableContext BC)
{   
     System.debug('made it to querylocator');

    return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Asset> assetList) {
System.debug('made it to execute');
      
  ///////////////////////////////////////////////////////////////////////////////
    

      
}   
      global void finish(Database.BatchableContext BC)
      {
      }
}

 
Our external website frequently makes API calls to Salesforce.  We want to notify customers that a portion of our site may be down when Salesforce has an issue.  Is there a way to programmatically tell upon user login, if the our instance has an outage and/or just have an incident reported?
I have a Visualforce page using a StandardController with an extension.  Everything works fine but when there are more than 100 items, and I hit the Save (updateSave()) button, I initialliy received the  "Apex governor limit warning".  I then changed the updateSave() to what is below and I then received Too many future calls: 51.

VFP
<apex:page standardController="Asset" docType="html-5.0"   lightningStylesheets="true" recordSetVar="assets" extensions="AssetUpdateController" tabStyle="Asset">
  <!-- Begin Default Content REMOVE THIS -->
<apex:form >
    <apex:pageBlock >
      <apex:pageMessages />
      <center>
       <apex:selectList value="{!productVersionItem}"   size="1" id="typeSelect">               
                  <apex:selectOptions value="{!dropProductVersionItems}"/>
                   <apex:actionSupport event="onchange"  action="{!rePopulateAzzets}"  >
                   </apex:actionsupport>                   
                </apex:selectList>
                </center><br />
      <apex:pageBlockButtons >
        <apex:commandButton value="Mark Listed Items as Inactive" 
                            action="{!groupMarkInactive}"/>
                             <apex:commandButton id="saveBtn" value="Save" action="{!updateSave}" />

          <apex:commandButton id="cancelBtn" value="Cancel" action="{!cancel}" />

      </apex:pageBlockButtons>
      <apex:pageBlockTable value="{!azzets}" 
                           var="ass">
       
        <apex:column headerValue="Asset Name">
     
          <apex:outputField value="{!ass.Name}"/>
        </apex:column>
        <apex:column headerValue="Quantity">
          <apex:outputField value="{!ass.Quantity}"/>
        </apex:column>
        
         <apex:column headerValue="PakSize">
          <apex:outputField value="{!ass.PakSize__c}"/>
        </apex:column>
         <apex:column headerValue="Product Family">
          <apex:outputField value="{!ass.ProductFamily}"/>
        </apex:column>
         <apex:column headerValue="Serial Number">
          <apex:outputField value="{!ass.SerialNumber}"/>
        </apex:column>
         <apex:column headerValue="Satus">
          <apex:inputField value="{!ass.Status}"/>
        </apex:column>
         <apex:column headerValue="Price">
          <apex:outputField value="{!ass.Price}"/>
        </apex:column>
         <apex:column headerValue="Purchase Date">
          <apex:outputField value="{!ass.PurchaseDate}"/>
        </apex:column>
      </apex:pageBlockTable>      
    </apex:pageBlock>
  </apex:form>
  <!-- End Default Content REMOVE THIS -->
</apex:page>

Controller
public  class AssetUpdateController {
      // TestAssetUpdateController
    @AuraEnabled
    public List<Asset> azzets{get;set;}   
    public String AcctId {get;set;} 
    public String productFamilyId {get;set;} 
    Public String productVersionItem{get;set;}
    Public List<SelectOption> dropProductVersionItems {get;set;}
    
    public AssetUpdateController(ApexPages.StandardSetController controller) {
        AcctId = System.currentPageReference().getParameters().get('Id');
        productFamilyId= System.currentPageReference().getParameters().get('PFId');
        getAzzets();
        
    }
    
    
    public List<Asset> getAzzets() {
        
        azzets = [Select Name, PurchaseDate, Price, Status, SerialNumber, ProductFamily, PakSize__c, Quantity 
                  From Asset where Account.id = :AcctId order by ProductFamily ASC];  
        
        dropProductVersionItems = new List<SelectOption>();
        dropProductVersionItems.add(new SelectOption('Filter By Version','Filter By Version'));
        
        //  List <Asset> productFamily = [SELECT ProductFamily  From Asset where Account.id = :AcctId Group by ProductFamily order by ProductFamily DESC];
        
        
        integer i = 0;
        while(i <  azzets.size())
        { 
            if (i==0) {
                dropProductVersionItems.add(new SelectOption(azzets[i].ProductFamily,azzets[i].ProductFamily));
                
            }else{
                if( (azzets[i].ProductFamily != azzets[i-1].ProductFamily))
                {
                    dropProductVersionItems.add(new SelectOption(azzets[i].ProductFamily,azzets[i].ProductFamily));
                }
                
            }
            
            i++;
        }           
        return azzets;    
        
    }
    
    public void rePopulateAzzets() {
        
        azzets = [Select Name, PurchaseDate, Price, Status, SerialNumber, ProductFamily, PakSize__c, Quantity 
                  From Asset where Account.id = :AcctId and ProductFamily = :productVersionItem];  
        
        
        
    }
    
    public void groupMarkInactive() {
        
        Integer i =0;
        while(i <  azzets.size())
        {
            azzets[i].Status = 'Inactive';
            i++;
        }               
        
    }
    
    public Pagereference updateSave() {  
        PageReference newpage = new Pagereference('/lightning/r/'+AcctId + '/related/Assets/view');
        try{
           // new code to work around Govenor Limit
            for(List<Asset> azzetsList : azzets)
            {
                for(Asset aAsset : azzetsList)
                {

                }
                Database.update(azzets);
            }

         // end new code to eliminate Governor Limit

        // Code below works but will cause Governor limit error if too many 
            // azzets.save();
           
            
        }catch(exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,e.getMessage()));
        }             
        
        newpage.setRedirect(true);        
        return newpage;
        
    }
    
    public Pagereference cancel(){
        
        PageReference newpage = new Pagereference('/'+AcctId);
        
        newpage.setRedirect(true);
        
        return newpage;
        
    }
}

​​​​​​​
I have successfully been able to add an emailMessage to SF via the API.  I will need to do one of the two options:
  1. Not have SF send the email to the recipient once added.  This is because we have already sent the email and just placing a copy in SF for our records
  2. Have the ability to change the fromAddress via the API.  If we remove the email sent from our website and only have the SF one to be sent, we will need to change the from email address.  I have added the email to the Organization-Wide Email addresses and associated it to the correct profile, however, I don't know where to switch it.
 
SingleEmailMessage emailMessage = new SingleEmailMessage();
            if (!string.IsNullOrEmpty(templateid))
            {
                emailMessage.templateId = templateid;
            }
            else
            {
                emailMessage.subject = subject;
                emailMessage.htmlBody = Server.UrlDecode(body) ;
            }

            emailMessage.toAddresses = new String[] { email };
            emailMessage.saveAsActivity = true;
            emailMessage.targetObjectId = contactId;

            SingleEmailMessage[] messages = { emailMessage };
            SendEmailResult[] results = binding.sendEmail(messages);

            if (results[0].success)
            {
                // Console.WriteLine("The email was sent successfully.");
            }
            else
            {
                SendEmail("xxxxxx@xxx.com", "Error SingleEmailMessage add", "The email failed to send: " + results[0].errors[0].message);

            }


            sflogout();

 
I have an apex function that while doing other tasks, also make a web call out.  I am not sure how to write a test for this.  I've found documentation for when I need to test a function that returns a HttpResponse but in my case the function returns a PageReference.

Controller Code
public  PageReference finalize() {
        
        String specialSerial;
        
        Integer i = 0;
        Integer size = products.size();
        test = '';
        List<List<String>> productswithSerial = new List<List<String>>{};
      
            ....

  string serial =   generate(prod2.ProductFamilyID__c, String.valueOf(products[i].Pak_Size__c));

.....
}

 
    public  string generate(decimal productFamily, string pak) {
        HttpRequest req = new HttpRequest();              
        HttpResponse res2 = new HttpResponse(); 
        Http http = new Http();
        req.setEndpoint('xxxxxxxxxxxxxxxx');              
        req.setMethod('GET');                  
        res2 = http.send(req);              
        if(res2.getstatusCode() == 200 && res2.getbody() != null){   
            return res2.getbody();
            //   test = test + '<br/>' + res2.getbody();                  
        }else{
            return 'Invalid';
        }
    }


My Test Code
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        
        // Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        HttpResponse res = tsc.finalize();
        
        // Verify response received contains fake values
        String contentType = res.getHeader('Content-Type');
        System.assert(contentType == 'application/json');
        String actualValue = res.getBody();
        String expectedValue = '{"xxxxxxxxxxxxxxxxxx"}';
        System.assertEquals(actualValue, expectedValue);
        System.assertEquals(200, res.getStatusCode());

I'm getting the error on this line "HttpResponse res = tsc.finalize();" which states "Illegal assignment from System.PageReference to System.HttpResponse" which I understand but don't know how to work-around.
 
This is strange.  I have apex:messages that work correctly in Lightning, however, in Classic they do not show.  After some researching, I tried putting the messages in an outputText.  But then it doesn't render with the set styling.  So for example, it renders the text in white but if I set it to black, red or any other color, it just ignores it and still puts it in white.  Any ideas?  Below are code snippets.
 
<div >
 <apex:Messages style="color:white;font-size:1.3em;font-weight:bold"/>

 <apex:outputText rendered="errorStatus" style="color:#ff0606;" value="{!errorMsg}" id="msg"/>


 </div>
 
if(Opp.StageName != 'Closed Won')
        {
            stageStatus = Opp.StageName;
            pageStatus = false;
            errorStatus = true;
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'The opportunity has not been won yet. You must mark the opportunity as Closed Won before finalizing it!'));
            errorMsg = 'The opportunity has not been won yet. You must mark the opportunity as Closed Won before finalizing it!';
        }

 
I can successfully post an email to Salesforce using the EmailMessage Object, however when I send a link, something like below, it strips out a portion of the URL parameters.  See below 

Link sent
https://www.xxxxxx.com/en-us/reset-password?login=xxx@somecompany.com&id=441810

Instead, I get 
https://www.xxxxxx.com/en-us/reset-password?login=xxx@somecompany.com


Anyone know why or how to fix?
 

In my class I have 3 global variables that I set on page load.  Then when a user clicks a button, those variables are used in a method that is invoked on click. This works fine.  However, when writing my test class, I keep receiving attempt to dereference a null object and it is pointing to those three variables.  

How do you set those variables within a test class?


 

I've created a VF page with controller in Lightning.  I found out that a department that hasn't migrated to Lightning yet also needs access.  However, when I go to add the VF page to the page layout in Classic, it isn't shown.  Is there a way to make it available in Classic.

Here is the VF page code
<apex:page lightningStylesheets="true" action="{!loadPage}" Controller="TrainingSubscriptionListController"  >
  <!-- Begin Default Content REMOVE THIS -->
  <apex:outputtext value="{!tmp}" escape="false" id="tblHTML"/>
  <!-- End Default Content REMOVE THIS -->
</apex:page>

and here is the contoller code
public class TrainingSubscriptionListController {
    @AuraEnabled
    Public List<Contact> acctContacts {get;set;}
    public string tmp {get;set;}
    
    public void loadPage(){
        string AcctId = System.currentPageReference().getParameters().get('Id');
        acctContacts = [Select Id, Training_Subscription_User__c, Name, Email from Contact where AccountId= :AcctId and Training_Subscription_User__c = true];
        
           tmp =     '<table id="myTable"  style="width:100%; table-layout: auto;" cellspacing="0" cellpadding="10"><tr>' + 
                '<td style="padding:15px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Name</b></td>' + 
                // '<td style="width:50px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                //'</td>' +
                '<td style=" background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Email</b></td>' +
                
                '</tr>';
            
            integer i = 0;              
            while(i <  acctContacts.size())
            {
                tmp = tmp + '<tr><td style="padding:15px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Name + '</a></td><td style="padding:5px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Email  +  '</a></td></tr>';
                i++;
            }
         tmp = tmp + '</table>';
    }

}

I've created custom fields for the Contact and Account objects.  The Contact fields are immediately available and can be queried with no problem.  The Account fields are not for some strange reason.  They have the same exact permissions, are visible in all page layouts, waited a couple of days to see if it was slow in updating, I've opened them up so that it is totally editable and yet nothing seems to work.  I can see the fields and query in Data Loader and Workbench.

Any ideas?
I have a VF page for the Account page that I needed to create in order to display Contacts that had a specific field check.  It simply queries Contacts with that field selected and displays.  When I tried to push this into production, I keep getting code coverage errors but I'm not sure how to create a test case for this.

Here is the Apex Code
public class TrainingSubscriptionListController {
    @AuraEnabled
    Public List<Contact> acctContacts {get;set;}
    public string tmp {get;set;}
    
    public void loadPage(){
        string AcctId = System.currentPageReference().getParameters().get('Id');
        acctContacts = [Select Id, Training_Subscription_User__c, Name, Email from Contact where AccountId= :AcctId and Training_Subscription_User__c = true];
        
           tmp =     '<table id="myTable"  style="width:100%; table-layout: auto;" cellspacing="0" cellpadding="10"><tr>' + 
                '<td style="padding:15px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Name</b></td>' + 
                // '<td style="width:50px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                //'</td>' +
                '<td style=" background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Email</b></td>' +
                
                '</tr>';
            
            integer i = 0;           
    
            
            while(i <  acctContacts.size())
            {
                tmp = tmp + '<tr><td style="padding:15px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Name + '</a></td><td style="padding:5px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Email  +  '</a></td></tr>';
                i++;
            }
         tmp = tmp + '</table>';
    }

}

I tried running it against this test but it fails as well.
@isTest
public class TestMultipleAdminCheck {
    @isTest static void TestContact() {
        Test.startTest();
        Account acct = new Account(Name='Test Account', Training_Subscription_Seats_Available__c = 1, Number_of_Support_Users__c = 1);
        insert acct;
        Contact cont1 = new Contact(FirstName='User', LastName='One',                                     
                                    AccountId=acct.Id, My_ASCI_Role__c = 'Support User');
        Contact cont2 = new Contact(FirstName='User', LastName='Two',                                     
                                    AccountId=acct.Id, My_ASCI_Role__c = 'Admin User', Training_Subscription_User__c = true);
        Contact cont3 = new Contact(FirstName='User', LastName='Three',                                     
                                    AccountId=acct.Id,    My_ASCI_Role__c = 'General User');
        Contact cont4 = new Contact(FirstName='User', LastName='Four',             
                                    AccountId=acct.Id,   My_ASCI_Role__c = 'Support User');
        insert cont1;
        insert cont2;
        insert cont3;
        insert cont4;
        
        
        Test.stopTest();
        
    }
    
}

Any help will be appreciated.
I have a checkbox field on the Contact object and would like to display all contacts that have that field selected to be displayed on the Account object.

What is the best way to accomplish this?
I have a picklist field on the Contact record but I only want one person from each account to have one of the picklist values selected in this case "Admin User".  The other picklist values may have mulitple contacts with the same item selected, just the Admin user needs to be unique.  

I'm assuming that I would have to write a trigger on Contact edit but how do I display the error to the user about to update the record?
So I have a pageblocktable that I populate with 
Public List<OpportunityLineItem> oppLineItem {get;set;}
 oppLineItem = [Select Id, Discount, ListPrice, TotalPrice,  PricebookEntryId, Product2Id, ProductCode, Name, Quantity,  UnitPrice, Description FROM OpportunityLineItem WHERE OpportunityId = :oppId];
What I would like to have happen is to group by Name and generate a sum for the Quantity. 

Is that possible or is there a better option than pageblocktable.  Note, I was only using the pageblocktable as I am not sure of how many items will be returned with the query.
 
I have a pageBlockTable that has things like Price, Discount and Total Price that are being populated by OpportunityLineItem List.  However, I need to add two Input fields (Upgrade Discount and New List Price) in each row.  When a user updates the Upgrade Discount for that Line Item, calculate what the new List price will be.

So in the screenshot below you can see that I want to adjust the New List Price for Test Product 2 after entering 30 .  The New List Price should be the List Price ($25,900) - the Upgrade Discount (30%)

User-added image
Salesforce will be ending support for Legacy SOAP API version 6 and lower.  I'm trying to confirm what SOAP version our app is using for the Outbound messages.  I tried to following the instructions given by the email by going into Workbench, exporting the EventLogFile and looking for API_Type.  However, I don't see that field. 

When I export via the Data Loader or the Salesforce Event Log File Browser, I don't see that field but do see something called API version.  Is that what I'm looking for?
I have a VF page that has various outcomes based upon user input.  How do I create a test to deploy into production?
VFP

<apex:page sidebar="false" Controller="SplitExecutionAgentController" > 
      <apex:pageBlock > 
         <apex:form >             
             <apex:outputPanel id="resultPanel">
             <apex:actionStatus startText="requesting..."  stopText="" id="myStatus" />                
          <apex:actionFunction action="{!createNewOpps}" name="createNewOppsAF" reRender="resultPanel" status="myStatus" >
              <apex:param name="firstParam" assignTo="{!linePak}" value="" />
              <apex:param name="secondParam" assignTo="{!lineQty}" value="" />
             </apex:actionFunction>
             
               <apex:actionFunction action="{!updateOpps}" name="updateOppsAF" reRender="resultPanel" status="myStatus" >
              <apex:param name="firstParam" assignTo="{!linePak}" value="" />
              <apex:param name="secondParam" assignTo="{!lineQty}" value="" />
             </apex:actionFunction>
             <apex:pageMessages />
                  </apex:outputPanel>
              <apex:inputHidden value="{!newOpps.TotalPrice}" id="totalPrice" />
        <apex:inputHidden value="{!newOpps.PricebookEntryID}" id="priceBookEntryId" />
        <apex:inputHidden value="{!newOpps.UnitPrice}" id="unitPrice" />
        <apex:inputHidden value="{!newOpps.ListPrice}" id="listPrice" />
        <apex:inputHidden value="{!newOpps.Description}" id="description" />
        
         </apex:form>           
 
            <table >        
        <tr>
        <td>
             <img src=" https://www.advsyscon.com/en-us/CorporateSite/media/Images/salesforce/splitexecutionagent2.png"  style="width: 75px; " />
            </td>
        <td>
            <h1 style="font-size:1.5em">
                Split Execution Agent Opportunity Product Line Item
            </h1>
            </td>
        </tr>
    </table>
    <hr /> 
    
    <FORM  METHOD="post" NAME="MyForm" ID="MyForm">
                             <b>  <output size="60" style="border:0; background:none; font-weight: bold;" NAME="pointsTotal" />  <br />
                         <script> document.MyForm.pointsTotal.value = "Found {!Text(newOpps.Quantity)} Total Execution Agent Points";</script>
                       <B>Points Remaining: </B><output disabled="true" style="border:0; background:none"  NAME="VarSum" VALUE="0" SIZE="15" MAXLENGTH="5" ONCHANGE="calculate(this)" />
              </b>
                       <script>
                           
                                 if("{!closedWon}" != 'true')
                                 {
                                     alert('This opportunity must be "Closed Won" in order to use this utility');
                                     window.history.back();
                                 }
                                
                                 if("{!Text(newOpps.Quantity)}")
                                 {
                                     document.MyForm.VarSum.value = "{!Text(newOpps.Quantity)}";                                  
                                     
                                 }else{
                                     
                                     
                                     if("{!totalCount}" == 0)
                                     {
                                         alert('Unable to locate an ActiveBatch Execution Agent product line item in this opportunity.');
                                         window.history.back();
                                     }else{
                                         alert("{!totalCount}" + ' ActiveBatch Execution Agent product line items were found in this opportunity.  Unfortunately the line-item splitter only works when a single Execution Agent line item is present in the opportunity.  To remedy the problem make sure that only one \"Execution Agent\" line item is present in your opportunity.  If you feel this is a SalesForce error, please contact your SalesForce administrator.');
                                         window.history.back();
                                     }                        
                                     
                                     
                                 }                               
                                 
                                 
                                 
                                 </script>
              <hr />
        <table id="myTable">
            <tbody>
            
                <th></th>
             <th><b>Quantity</b></th>
        <th></th>
        <th><b>PakSize (Points)</b></th>        
            <tr>
                <td> <INPUT TYPE="button" style="visibility:hidden" disabled="true" NAME="id" /></td>
            <td> <INPUT TYPE="text" Id="qty0" NAME="qty0" VALUE="0" onfocus="this.value=''" ONCHANGE="calculate(this)" SIZE="15" MAXLENGTH="5"  />
                </td>
             <td  style="width:50px"></td>
            <td>
                 <INPUT TYPE="text" Id="pak0" NAME="pak0" VALUE="0" SIZE="15" MAXLENGTH="5" ONCHANGE="calculate(this)" /></td></tr>
            </tbody>
        </table>
        <input type="button" Id="addMore" name="addMore" value="Add Another Multiple" onclick="generateItem();" /> 

        <hr size="1" color="#c6c6c6" /> 
                                 <table>
                                      <tr>
         <td >      
                 <input type="button" Id="splitItems" name="splitItems" style="visibility:hidden" value="Update Opportunity" onclick="updateOpportunity();" />     
             </td>
             <td>
                 <input type="button" id="cmdCancel" onclick="window.history.go(-1); return false;"  value="Cancel" />
            </td></tr>                                     
                                 </table>                                
        
        </FORM>             
       
            </apex:pageBlock>                       

 
     <!-- Java script starts Here -->
    <script type="text/javascript">
    var counter = 0;   
        var showButtons = new Boolean(true);
    
    function calculate(which)
    {
        var runningTotal = 0;         
       
         var qty;
         var pak;
        var i = 0;
        //alert('counter = ' + counter + ' and i = ' + i);
         while(i <= counter )
            {            
                qty = parseInt(document.getElementById("myTable").rows[i + 1].cells[1].getElementsByTagName("input")[0].value);
                pak =  parseInt(document.getElementById("myTable").rows[i + 1].cells[3].getElementsByTagName("input")[0].value);                
                runningTotal = runningTotal + (qty * pak); 
                
                 if ((pak % 5) != 0){ 
                alert("All paksize point values must be divisible by 5! " + pak + " is not a valid PakSize. You must fix this error to continue."); 
                return; 
                    }
         
                i++       
                     
            }        

        var total = "{!Text(newOpps.Quantity)}";
        var remaining = total - runningTotal;
        
        if(remaining < 0){
            
             document.MyForm.VarSum.value = remaining;
            alert('You have allocated too many points. You must reallocate the point usage before continuing.');
            
            //disable buttons
              hideButtons();       
            
            
            }else{
                document.MyForm.VarSum.value = remaining;
                document.getElementById('addMore').style.visibility = 'visible';                
                 document.getElementById('splitItems').style.visibility = 'hidden';
                
                
                }
        
        if(remaining == 0){
            
              document.getElementById('addMore').style.visibility = 'hidden';                
                document.getElementById('splitItems').style.visibility = 'visible'; 
            }
     return; 
    }
        
   function hideButtons()
        {
             document.getElementById('splitItems').style.visibility = 'hidden';
             document.getElementById('addMore').style.visibility = 'hidden';
           
            }
        
        function showButtons()
        {
              document.getElementById('splitItems').style.visibility = 'visible';
             document.getElementById('addMore').style.visibility = 'visible';
            }
function goBack()
{
    window.history.go(-1); return false;
    }
function generateItem()
{
    counter++;

    var tableRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];
    
    // Insert a row in the table at the last row
	var newRow   = tableRef.insertRow(tableRef.rows.length);
    newRow.name =  counter;

	// Insert a cell in the row at index 0
	var newCell0  = newRow.insertCell(0);

	// Append a text node to the cell
     var h0 = document.createElement("button");
    h0.setAttribute('onclick', 'deleteRow(this)');
	newCell0.appendChild(h0);
    //  alert('Delete2 newRow.name = ' + newRow.name);
     var t0 = document.createTextNode("Delete Row");
    h0.appendChild(t0);
	newCell0.appendChild(h0);
    
    // Insert a cell in the row at index 0
	var newCell1  = newRow.insertCell(1);
	// Append a text node to the cell
     var h1 = document.createElement("input");
    h1.Name = 'qty'+ counter;
     h1.value = 0;
    h1.setAttribute('size', '15'); 
      h1.setAttribute('onchange', 'calculate(this)');
	newCell1.appendChild(h1);
    
     // Insert a cell in the row at index 0
	var newCell3  = newRow.insertCell(2);
	// Append a text node to the cell
    //var h3 = document.createElement("input");

       
    //newCell3.appendChild(h3);
    
   // Insert a cell in the row at index 0
	var newCell2  = newRow.insertCell(3);
	// Append a text node to the cell
     var h2 = document.createElement("input");
     h2.Name = 'pak'+ counter;
     h2.setAttribute('size', '15');
     h2.value = 0;
       h2.setAttribute('onchange', 'calculate(this)');
	newCell2.appendChild(h2);   
    
    }

 function deleteRow(el)
    {
        //  alert('invoked');
         while (el.parentNode && el.tagName.toLowerCase() != 'tr') {
        el = el.parentNode;
        }
          el.parentNode.removeChild(el);
        counter--;
        calculate(this);
        }

function updateOpportunity()
{
         var runningTotal = 0;         
       
         var qty;
         var pak;
        var i = 0;
        //alert('counter = ' + counter + ' and i = ' + i);
         while(i <= counter )
            {            
                qty = parseInt(document.getElementById("myTable").rows[i + 1].cells[1].getElementsByTagName("input")[0].value);
                pak =  parseInt(document.getElementById("myTable").rows[i + 1].cells[3].getElementsByTagName("input")[0].value);                
                runningTotal = runningTotal + (qty * pak); 
                
                 if ((pak % 5) != 0){ 
                alert("All paksize point values must be divisible by 5! " + pak + " is not a valid PakSize. You must fix this error to continue."); 
                return; 
                    }
                
                // if i = 0 then we update the existing product line item
                // Otherwise we need to add them
                if(i ==0)
                {
                    updateOppsAF(pak, qty);
                    //alert("update existing with " + qty + " " + pak);
                }else{
                     createNewOppsAF(pak, qty);
                    //  alert("create new with "  + qty + " " + pak);
                }               
                    
         
                i++       
                     
            } 
    alert('Success');
    reDirect();
    
 
    }
     
     function reDirect()
     {
         window.location = '/' + "{!retURL}";
         }
     
    
  </script> 
</apex:page>

Controller


public  class SplitExecutionAgentController {
   @AuraEnabled
    
    public Boolean showButtons {get;set;} 
    public String closedWon {get;set;}
    Public Integer pointsTotal {get;set;} 
    Public Integer points {get;set;} 
    Public Integer pak {get;set;} 
     Public String retURL {get;set;} 
    
    Public String totalPrice {get;set;} 
    Public String PricebookEntryID {get;set;} 
    Public Integer unitPrice {get;set;} 
    Public Integer listPrice {get;set;} 
    Public String description {get;set;} 
    
    Public Integer linePak {get;set;} 
    Public Integer lineQty {get;set;} 
    
    Public Integer totalCount {get;set;} 
    Public String test {get;set;} 
   
    
     public PageReference setParams()
    {
        return null;
    }
      
  public OpportunityLineItem getNewOpps() {
      retURL = System.currentPageReference().getParameters().get('Id');
      Opportunity Opp = [SELECT stagename FROM Opportunity WHERE Id = :System.currentPageReference().getParameters().get('Id')];
      
      if(Opp.StageName == 'Closed Won')
      {
          closedWon = 'true';
      }else{
          closedWon = 'false';
      }
      totalCount= [SELECT count() FROM OpportunityLineItem WHERE PricebookEntry.Name LIKE '%Execution Agent%' AND OpportunityId = :System.currentPageReference().getParameters().get('Id')];
      
      if(totalCount == 0)
      {
          showButtons = false;
          ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Unable to locate an ActiveBatch Execution Agent product line item in this opportunity.'));
          return null;
      }
      
      if(totalCount > 1)
      {
          showButtons = false;
          ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,totalCount + ' ActiveBatch Execution Agent product line items were found in this opportunity.  Unfortunately the line-item splitter only works when a single Execution Agent line item is present in the opportunity.  To remedy the problem make sure that only one \"Execution Agent\" line item is present in your opportunity.  If you feel this is a SalesForce error, please contact your SalesForce administrator.'));
         
          return null;
      }
     
      OpportunityLineItem A;
      A = [SELECT Id, Quantity, PricebookEntryID, TotalPrice, UnitPrice, ListPrice, Description  FROM OpportunityLineItem WHERE PricebookEntry.Name LIKE '%Execution Agent%' AND OpportunityId =  :System.currentPageReference().getParameters().get('Id')];     
     PricebookEntryID = A.PricebookEntryId;	
       
      pointsTotal = Integer.valueOf(A.Quantity);
      points = Integer.valueOf(A.Quantity);
      unitPrice = Integer.valueOf(A.UnitPrice);
      listPrice = Integer.valueOf(A.ListPrice);
       
       return A;
  }  
    
     public OpportunityLineItem updateOpps() { 
          Integer lineCount = 2;
         OpportunityLineItem A;
      A = [SELECT Id, Quantity, PricebookEntryID, TotalPrice, UnitPrice, ListPrice, Description  FROM OpportunityLineItem WHERE PricebookEntry.Name LIKE '%Execution Agent%' AND OpportunityId =  :System.currentPageReference().getParameters().get('Id')];     

         A.Quantity = Integer.valueOf(linePak);
         A.TotalPrice = (Decimal.valueOf(unitPrice) * Integer.valueOf(linePak));

         update A; 
         
          while (lineCount <= Integer.valueOf(lineQty)) {         
         OpportunityLineItem OLI = new OpportunityLineItem();
         OLI.OpportunityId = System.currentPageReference().getParameters().get('Id');
         OLI.PricebookEntryId = priceBookEntryId; //PriceBookEntry Id for that Product should be assigned.
         OLI.Quantity = Integer.valueOf(linePak);
         OLI.TotalPrice = (Decimal.valueOf(unitPrice) * Integer.valueOf(linePak));
         OLI.Description = description;
         insert OLI;
             lineCount++;
         }
     
         return null;
  }   
    
     public OpportunityLineItem createNewOpps() {
         
         Integer lineCount = 1;
         
         while (lineCount <= Integer.valueOf(lineQty)) {         
         OpportunityLineItem OLI = new OpportunityLineItem();
         OLI.OpportunityId = System.currentPageReference().getParameters().get('Id');
         OLI.PricebookEntryId = priceBookEntryId; //PriceBookEntry Id for that Product should be assigned.
         OLI.Quantity = Integer.valueOf(linePak);
         OLI.TotalPrice = (Decimal.valueOf(unitPrice) * Integer.valueOf(linePak));
         OLI.Description = description;
         insert OLI;
             lineCount++;
         }
     
         return null;
  }   
}
Attempted Test Class

    @isTest
public class testSplit { 
    
    @isTest static void testSplit()   {
        //Account acct = new Account(Name='Test Account');
        Account acct = new Account(Name='Test Account', Sales_Tax__c=2, Wire_Fee__c=25);
       
System.debug('Start enter contact');        
        Contact contact = new Contact(Email = 'test@test.com', Marketing_Qualified_Action__c = 'Option1', FirstName = 'Test', LastName= 'Tester', AccountId = acct.Id);
        insert contact; 
        
      

 System.debug('Start enter opportunities');       
        Opportunity opp = new Opportunity(Name=acct.Name + ' Opportunity',  StageName='Closed Won',Support_Amount__c =20, VUP_Amount__c = 20, Sales_Tax__c=2, Wire_Fee__c =20, Prorated_Amount__c =100.00, CloseDate=System.today().addMonths(1), AccountId=acct.Id);
        insert opp;
       
         Opportunity opp2 = new Opportunity(Name=acct.Name + ' Opportunity', StageName='Prospecting',  Support_Amount__c =20, VUP_Amount__c = 20, Sales_Tax__c=2, Wire_Fee__c =20, Prorated_Amount__c =100.00, CloseDate=System.today().addMonths(1), AccountId=acct.Id);
        insert opp2;
        
 Id pricebookId = Test.getStandardPricebookId();       
        //Create your product
Product2 prod = new Product2(Name = 'Execution Agent Points',  ProductCode = 'Pro-X', isActive = true, ProductFamilyID__c=173, Invoice_Description__c='test');
insert prod;

//Create your pricebook entry
PricebookEntry pbEntry = new PricebookEntry(Pricebook2Id=pricebookId, Product2Id = prod.Id,  UnitPrice = 100.00, IsActive = true);
insert pbEntry;
        
         //SELECT Id, Quantity, PricebookEntryID, TotalPrice, UnitPrice, ListPrice, Description  FROM OpportunityLineItem WHERE PricebookEntry.Name LIKE '%Execution Agent%' AND OpportunityId =  :System.currentPageReference().getParameters().get('Id')
       OpportunityLineItem opline = new OpportunityLineItem(PricebookEntryId=pbEntry.Id, OpportunityId=opp.Id, Quantity=20,TotalPrice=20  * pbEntry.UnitPrice);
        insert opline;
            
             OpportunityLineItem opline2 = new OpportunityLineItem(PricebookEntryId = pbEntry.Id, OpportunityId= opp2.Id, Quantity=20,TotalPrice = 20  * pbEntry.UnitPrice);
        insert opline2;
            
             OpportunityLineItem opline3 = new OpportunityLineItem(PricebookEntryId = pbEntry.Id, OpportunityId= opp.Id, Quantity=20,TotalPrice = 20  * pbEntry.UnitPrice);
        insert opline3;
        
        
  System.debug('Start enter test');   
        
        // Perform test
        Test.startTest();
			ApexPages.currentPage().getParameters().put('id', String.valueOf(opp.Id));
			SplitExecutionAgentController  testAccPlan = new SplitExecutionAgentController();
			testAccPlan.updateOpps();
			testAccPlan.createNewOpps ();
        
        	ApexPages.currentPage().getParameters().put('id', String.valueOf(opp2.Id));
			SplitExecutionAgentController  testAccPlan2 = new SplitExecutionAgentController();
			testAccPlan2.updateOpps();
			testAccPlan2.createNewOpps ();

		Test.StopTest();
       
   


    }



}


 
Not sure why I'm having a problem with this.  I need a button (Lightning Controller) that will open two urls in separate tabs passing the CaseNumber parameter.  I can open the two URLs but can't seem to be able to pass the parameter.

WebExRedirect.cmp
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" >
    <aura:attribute type="Case" name="case"/>

    <ui:button label="WebEx2"    press="{!c.openActionWindow}"/>
</aura:component>
And my WebExRedirectController.js
({
	openActionWindow : function(component, event, helper) {
        if (confirm("Are you sure you want to Initiate a Webex support session for this case?")) 
{    
   var caseid ={!v.CaseNumber};


window.open("www.someURL?" + caseid + "&level=2");
window.open("www.someURL?" + caseid + "&level=2");
	}
    }
})

Please help

 
I'm clearly missing something in this process.  I have a VF page that looks like this
User-added image

What I would like to have happen is for the "Points Remaining" to total the number of "Found xx Total Exeuction Agent Points" minus the PakSize Input text amount.  

Problems:
  1. With my code below, I don't understand why on page load, it processes the getCount() Method.  
  2. I have been unsuccessful in passing the input field (pak) to Apex
VF Page
<table  >      
             <tr>
              <td colspan="10">              
                     <b>  <apex:outputText value="Found {!Text(newOpps.Quantity)} Total Execution Agent Points " id="pointsTotal" />  <br />
                      <apex:outputText value="Points Remaining: {!count}"   id="pointsRemaining" label=""/>
              </b>
              <hr />
              </td>
             </tr>
        <th><b>Quantity</b></th>
        <th></th>
        <th><b>PakSize (Points)</b></th>
             
        <tr>
        <td> 
             <apex:inputText id="quantity"  required="true"  />
            </td>
            <td rowspan="20" style="width:50px">
            </td>
        <td>
           
              <apex:outputpanel id="panel1">
           			 <apex:inputText id="pak"    value="{!pak}"   />                 
                    <apex:actionSupport event="onchange"  action="{!getCount}" status="counterStatus2" rerender="pointsRemaining"/>
                    </apex:outputpanel> 
            <apex:actionStatus id="counterStatus2" startText=" (Calculating...)" stopText=" (Completed)"/>

            </td>           
        </tr>
           
        <tr>
        <td colspan="3">
   <center>
          <apex:commandButton id="cmdaddLine" disabled="{!showButtons}" value="Add Another Multiple" />
   </center> 
         </td></tr>
        <tr>
         <td colspan="3">
            <hr />
            </td></tr>
        <tr>
         <td colspan="2">      
               <apex:commandButton id="cmdupdateOpp" disabled="{!showButtons}" value="Update Opportunity" />       
             </td>
             <td>
                 <apex:commandButton id="cmdCancel" onclick="window.history.go(-1); return false;"  value="Cancel" />
            </td></tr>
             <!-- </apex:repeat> -->
     </table>


Apex Code:
public  class SplitExecutionAgentController {
   @AuraEnabled
    
    public Boolean showButtons {get;set;}
    Integer pointsTotal = 0;
    Public Integer points {get;set;} 
    Integer count = 0;
    Public Integer pak {get;set;} // input text1 value  from vf
   
    
     public PageReference setParams()
    {
        return null;
    }
      
  public OpportunityLineItem getNewOpps() {     
      OpportunityLineItem A;
      A = [SELECT Id, Quantity, PricebookEntryID, TotalPrice, UnitPrice, ListPrice, Description  FROM OpportunityLineItem WHERE PricebookEntry.Name LIKE '%Execution Agent%' AND OpportunityId =  :System.currentPageReference().getParameters().get('Id')];      
         
      pointsTotal = Integer.valueOf(A.Quantity);
     points = Integer.valueOf(A.Quantity);
     count = Integer.valueOf(A.Quantity);
      pak = 0;
     
       return A;
  }    


                    
    public Integer getCount() {
        points = pointstotal - pak ;     
 
        return points;
    }
    
   
}


 
I've tested my Lightning Component and it worked as expected and see Contacts for displayed in my component.  Another user looking at the same account sees "There are no Team Lead or Support contacts"
public  class accController {
    @AuraEnabled
    public static list<Contact> getTrainingSubscription(Id recordId)
    {
        List<Contact> Conlist = [Select Id, Training_Subscription_User__c, Name, Email, Contact_Status__c, Last_Training_Login_Date__c from Contact where AccountId= :recordId and Training_Subscription_User__c = true ORDER By Contact_Status__c];
        return Conlist;
    }

    @AuraEnabled
    public static list<Contact> getSupportUsers(Id recordId)
    {
        List<Contact> Conlist =  [SELECT Id, Email,My_ASCI_Role__c,Name,  Experience__c FROM Contact WHERE  AccountId=:recordId AND (My_ASCI_Role__c = 'Team Lead' OR My_ASCI_Role__c = 'Support User') order by My_ASCI_Role__c desc];
        return Conlist;
    }

     @AuraEnabled
    public static decimal getAverageExperience(Id recordId)
    {      

      
        List<Contact> acctContacts = [SELECT Id, Email,My_ASCI_Role__c,Name,  Experience__c FROM Contact WHERE  AccountId=:recordId AND (My_ASCI_Role__c = 'Team Lead' OR My_ASCI_Role__c = 'Support User') order by My_ASCI_Role__c desc];
              integer j = 0; 
        decimal avgExperience = 0;
            while(j <  acctContacts.size())
            {
              avgExperience = avgExperience + acctContacts[j].Experience__c;
                   
                j++;
            } 
        
        if(acctContacts.size() != null && acctContacts.size() != 0)
        {
            avgExperience = (avgExperience / acctContacts.size());
        }
        return avgExperience;
    }

     @AuraEnabled
    public static Integer getSubPurchased(Id recordId)
    {    
       List<Account>  acct = [Select Id, Training_Subscription_Seats_Available__c FROM Account where Id= :recordId];  

      return   Integer.valueOf(acct[0].Training_Subscription_Seats_Available__c);
      
    }

     @AuraEnabled
    public static Integer getSubLeft(Id recordId)
    {      
        List<Account>  acct = [Select Id, Training_Subscription_Seats_Available__c FROM Account where Id= :recordId];  
        List <Contact>  acctContacts = [Select Id, Training_Subscription_User__c, Name, Email, Contact_Status__c, Last_Training_Login_Date__c from Contact where AccountId= :recordId and Training_Subscription_User__c = true ORDER By Contact_Status__c];
      
      return  Integer.valueOf(acct[0].Training_Subscription_Seats_Available__c) - acctContacts.size();
    }




     
       
}
 
<aura:component controller="accController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <!--testComponentTrngSubSupportUsers-->
     <aura:attribute name="recordId" type="Id" access="global" />
    <aura:attribute name="ContactList" type="Contact[]" access="global" />
    <aura:attribute name="avg" type="Decimal" access="global" />
     <aura:handler name="init" value="{!this}" action="{!c.myAction}" access="global" />
     <lightning:card iconName="standard:case_wrap_up" title="Team Lead and Support User List">
     <aura:if isTrue="{!not(empty(v.ContactList))}">
         <center>Average Experience: <lightning:formattedNumber value="{!v.avg}"/> days</center>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
         <thead>
            <tr class="slds-text-title">
                <th  style="padding-left:10px;background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Name">Name</div>
                </th>
                <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Email">Email</div>
                </th>
                 <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                     <div class="slds-truncate" title="Experience">Experience</div>
                </th>
                <th  style="background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;" scope="col">
                    <div class="slds-truncate" title="Role">My ASCI<br/>Role</div>
                </th>
            </tr>
        </thead>
        <tbody>
   
    <aura:iteration   items="{!v.ContactList}" var="con">
        <tr>
                    <td data-label="Name" style="padding-left:10px">
                        
                      
                         <div class="slds-truncate" title="">
                             <lightning:formattedUrl  value="{! '/' + con.Id}" label="{!con.Name}"  target="_blank" />
                             </div>
                    </td>
                    <td data-label="Email">
                        <div class="slds-truncate" title="">
                             <lightning:formattedUrl  value="{! '/' + con.Id}" label="{!con.Email}"  target="_blank" /></div>
                    </td>
             <td data-label="Experience">
                        <div class="slds-truncate" title=""><lightning:formattedNumber value="{!con.Experience__c}"/> days</div>
                    </td>
                    <td data-label="Role">
                        <div class="slds-truncate" title="">{!con.My_ASCI_Role__c}</div>
                    </td>
                </tr>
        
       
    </aura:iteration>
        </tbody>
         </table>
	  <aura:set attribute="else">
                <div Style="text-align : center">  There are no Team Lead or Support contacts </div>
            </aura:set>
        </aura:if>
    </lightning:card>
	
</aura:component>
 
({
 myAction : function(component, event, helper) 
    {
        var ConList = component.get("c.getSupportUsers");
        ConList.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        ConList.setCallback(this, function(data) 
                           {
                               component.set("v.ContactList", data.getReturnValue());
                           });
        $A.enqueueAction(ConList);
        
        
        var avg = component.get("c.getAverageExperience");
        avg.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        avg.setCallback(this, function(data) 
                           {
                               component.set("v.avg", data.getReturnValue());
                           });
        $A.enqueueAction(avg);
        
        
 }
})

I've tried the code below (removed some items for confidentiality) but I receive the "made it to the query locator" debug message but never receive the "made it to the execute" debug.  I'm calling it by entering

batchGenerateAssets be = new batchGenerateAssets();
database.executeBatch(be);

in Execute Anonymous Window of the Developer Console

 

What am I doing wrong?

global class batchGenerateAssets implements Database.Batchable<sObject>, Database.AllowsCallouts{

 public String query = 'Select Id, PakSize__c, ProductFamily, UsageEndDate, Product2Id  FROM Asset WHERE SerialNumber = \'**Generate**\' ';

global Database.QueryLocator start(Database.BatchableContext BC)
{   
     System.debug('made it to querylocator');

    return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Asset> assetList) {
System.debug('made it to execute');
      
  ///////////////////////////////////////////////////////////////////////////////
    

      
}   
      global void finish(Database.BatchableContext BC)
      {
      }
}

 
I have a Visualforce page using a StandardController with an extension.  Everything works fine but when there are more than 100 items, and I hit the Save (updateSave()) button, I initialliy received the  "Apex governor limit warning".  I then changed the updateSave() to what is below and I then received Too many future calls: 51.

VFP
<apex:page standardController="Asset" docType="html-5.0"   lightningStylesheets="true" recordSetVar="assets" extensions="AssetUpdateController" tabStyle="Asset">
  <!-- Begin Default Content REMOVE THIS -->
<apex:form >
    <apex:pageBlock >
      <apex:pageMessages />
      <center>
       <apex:selectList value="{!productVersionItem}"   size="1" id="typeSelect">               
                  <apex:selectOptions value="{!dropProductVersionItems}"/>
                   <apex:actionSupport event="onchange"  action="{!rePopulateAzzets}"  >
                   </apex:actionsupport>                   
                </apex:selectList>
                </center><br />
      <apex:pageBlockButtons >
        <apex:commandButton value="Mark Listed Items as Inactive" 
                            action="{!groupMarkInactive}"/>
                             <apex:commandButton id="saveBtn" value="Save" action="{!updateSave}" />

          <apex:commandButton id="cancelBtn" value="Cancel" action="{!cancel}" />

      </apex:pageBlockButtons>
      <apex:pageBlockTable value="{!azzets}" 
                           var="ass">
       
        <apex:column headerValue="Asset Name">
     
          <apex:outputField value="{!ass.Name}"/>
        </apex:column>
        <apex:column headerValue="Quantity">
          <apex:outputField value="{!ass.Quantity}"/>
        </apex:column>
        
         <apex:column headerValue="PakSize">
          <apex:outputField value="{!ass.PakSize__c}"/>
        </apex:column>
         <apex:column headerValue="Product Family">
          <apex:outputField value="{!ass.ProductFamily}"/>
        </apex:column>
         <apex:column headerValue="Serial Number">
          <apex:outputField value="{!ass.SerialNumber}"/>
        </apex:column>
         <apex:column headerValue="Satus">
          <apex:inputField value="{!ass.Status}"/>
        </apex:column>
         <apex:column headerValue="Price">
          <apex:outputField value="{!ass.Price}"/>
        </apex:column>
         <apex:column headerValue="Purchase Date">
          <apex:outputField value="{!ass.PurchaseDate}"/>
        </apex:column>
      </apex:pageBlockTable>      
    </apex:pageBlock>
  </apex:form>
  <!-- End Default Content REMOVE THIS -->
</apex:page>

Controller
public  class AssetUpdateController {
      // TestAssetUpdateController
    @AuraEnabled
    public List<Asset> azzets{get;set;}   
    public String AcctId {get;set;} 
    public String productFamilyId {get;set;} 
    Public String productVersionItem{get;set;}
    Public List<SelectOption> dropProductVersionItems {get;set;}
    
    public AssetUpdateController(ApexPages.StandardSetController controller) {
        AcctId = System.currentPageReference().getParameters().get('Id');
        productFamilyId= System.currentPageReference().getParameters().get('PFId');
        getAzzets();
        
    }
    
    
    public List<Asset> getAzzets() {
        
        azzets = [Select Name, PurchaseDate, Price, Status, SerialNumber, ProductFamily, PakSize__c, Quantity 
                  From Asset where Account.id = :AcctId order by ProductFamily ASC];  
        
        dropProductVersionItems = new List<SelectOption>();
        dropProductVersionItems.add(new SelectOption('Filter By Version','Filter By Version'));
        
        //  List <Asset> productFamily = [SELECT ProductFamily  From Asset where Account.id = :AcctId Group by ProductFamily order by ProductFamily DESC];
        
        
        integer i = 0;
        while(i <  azzets.size())
        { 
            if (i==0) {
                dropProductVersionItems.add(new SelectOption(azzets[i].ProductFamily,azzets[i].ProductFamily));
                
            }else{
                if( (azzets[i].ProductFamily != azzets[i-1].ProductFamily))
                {
                    dropProductVersionItems.add(new SelectOption(azzets[i].ProductFamily,azzets[i].ProductFamily));
                }
                
            }
            
            i++;
        }           
        return azzets;    
        
    }
    
    public void rePopulateAzzets() {
        
        azzets = [Select Name, PurchaseDate, Price, Status, SerialNumber, ProductFamily, PakSize__c, Quantity 
                  From Asset where Account.id = :AcctId and ProductFamily = :productVersionItem];  
        
        
        
    }
    
    public void groupMarkInactive() {
        
        Integer i =0;
        while(i <  azzets.size())
        {
            azzets[i].Status = 'Inactive';
            i++;
        }               
        
    }
    
    public Pagereference updateSave() {  
        PageReference newpage = new Pagereference('/lightning/r/'+AcctId + '/related/Assets/view');
        try{
           // new code to work around Govenor Limit
            for(List<Asset> azzetsList : azzets)
            {
                for(Asset aAsset : azzetsList)
                {

                }
                Database.update(azzets);
            }

         // end new code to eliminate Governor Limit

        // Code below works but will cause Governor limit error if too many 
            // azzets.save();
           
            
        }catch(exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,e.getMessage()));
        }             
        
        newpage.setRedirect(true);        
        return newpage;
        
    }
    
    public Pagereference cancel(){
        
        PageReference newpage = new Pagereference('/'+AcctId);
        
        newpage.setRedirect(true);
        
        return newpage;
        
    }
}

​​​​​​​
I have successfully been able to add an emailMessage to SF via the API.  I will need to do one of the two options:
  1. Not have SF send the email to the recipient once added.  This is because we have already sent the email and just placing a copy in SF for our records
  2. Have the ability to change the fromAddress via the API.  If we remove the email sent from our website and only have the SF one to be sent, we will need to change the from email address.  I have added the email to the Organization-Wide Email addresses and associated it to the correct profile, however, I don't know where to switch it.
 
SingleEmailMessage emailMessage = new SingleEmailMessage();
            if (!string.IsNullOrEmpty(templateid))
            {
                emailMessage.templateId = templateid;
            }
            else
            {
                emailMessage.subject = subject;
                emailMessage.htmlBody = Server.UrlDecode(body) ;
            }

            emailMessage.toAddresses = new String[] { email };
            emailMessage.saveAsActivity = true;
            emailMessage.targetObjectId = contactId;

            SingleEmailMessage[] messages = { emailMessage };
            SendEmailResult[] results = binding.sendEmail(messages);

            if (results[0].success)
            {
                // Console.WriteLine("The email was sent successfully.");
            }
            else
            {
                SendEmail("xxxxxx@xxx.com", "Error SingleEmailMessage add", "The email failed to send: " + results[0].errors[0].message);

            }


            sflogout();

 
I can successfully post an email to Salesforce using the EmailMessage Object, however when I send a link, something like below, it strips out a portion of the URL parameters.  See below 

Link sent
https://www.xxxxxx.com/en-us/reset-password?login=xxx@somecompany.com&id=441810

Instead, I get 
https://www.xxxxxx.com/en-us/reset-password?login=xxx@somecompany.com


Anyone know why or how to fix?
 

In my class I have 3 global variables that I set on page load.  Then when a user clicks a button, those variables are used in a method that is invoked on click. This works fine.  However, when writing my test class, I keep receiving attempt to dereference a null object and it is pointing to those three variables.  

How do you set those variables within a test class?


 

I've created a VF page with controller in Lightning.  I found out that a department that hasn't migrated to Lightning yet also needs access.  However, when I go to add the VF page to the page layout in Classic, it isn't shown.  Is there a way to make it available in Classic.

Here is the VF page code
<apex:page lightningStylesheets="true" action="{!loadPage}" Controller="TrainingSubscriptionListController"  >
  <!-- Begin Default Content REMOVE THIS -->
  <apex:outputtext value="{!tmp}" escape="false" id="tblHTML"/>
  <!-- End Default Content REMOVE THIS -->
</apex:page>

and here is the contoller code
public class TrainingSubscriptionListController {
    @AuraEnabled
    Public List<Contact> acctContacts {get;set;}
    public string tmp {get;set;}
    
    public void loadPage(){
        string AcctId = System.currentPageReference().getParameters().get('Id');
        acctContacts = [Select Id, Training_Subscription_User__c, Name, Email from Contact where AccountId= :AcctId and Training_Subscription_User__c = true];
        
           tmp =     '<table id="myTable"  style="width:100%; table-layout: auto;" cellspacing="0" cellpadding="10"><tr>' + 
                '<td style="padding:15px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Name</b></td>' + 
                // '<td style="width:50px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                //'</td>' +
                '<td style=" background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Email</b></td>' +
                
                '</tr>';
            
            integer i = 0;              
            while(i <  acctContacts.size())
            {
                tmp = tmp + '<tr><td style="padding:15px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Name + '</a></td><td style="padding:5px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Email  +  '</a></td></tr>';
                i++;
            }
         tmp = tmp + '</table>';
    }

}

I have a VF page for the Account page that I needed to create in order to display Contacts that had a specific field check.  It simply queries Contacts with that field selected and displays.  When I tried to push this into production, I keep getting code coverage errors but I'm not sure how to create a test case for this.

Here is the Apex Code
public class TrainingSubscriptionListController {
    @AuraEnabled
    Public List<Contact> acctContacts {get;set;}
    public string tmp {get;set;}
    
    public void loadPage(){
        string AcctId = System.currentPageReference().getParameters().get('Id');
        acctContacts = [Select Id, Training_Subscription_User__c, Name, Email from Contact where AccountId= :AcctId and Training_Subscription_User__c = true];
        
           tmp =     '<table id="myTable"  style="width:100%; table-layout: auto;" cellspacing="0" cellpadding="10"><tr>' + 
                '<td style="padding:15px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Name</b></td>' + 
                // '<td style="width:50px; background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                //'</td>' +
                '<td style=" background-color: #0084c4 !important;background-image: none !important; color: #ffffff !important; font-size:100% !important; margin:0 !important; border:none !important;">' +
                '<b>Email</b></td>' +
                
                '</tr>';
            
            integer i = 0;           
    
            
            while(i <  acctContacts.size())
            {
                tmp = tmp + '<tr><td style="padding:15px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Name + '</a></td><td style="padding:5px;"><a href="/' + acctContacts[i].Id + '">' + acctContacts[i].Email  +  '</a></td></tr>';
                i++;
            }
         tmp = tmp + '</table>';
    }

}

I tried running it against this test but it fails as well.
@isTest
public class TestMultipleAdminCheck {
    @isTest static void TestContact() {
        Test.startTest();
        Account acct = new Account(Name='Test Account', Training_Subscription_Seats_Available__c = 1, Number_of_Support_Users__c = 1);
        insert acct;
        Contact cont1 = new Contact(FirstName='User', LastName='One',                                     
                                    AccountId=acct.Id, My_ASCI_Role__c = 'Support User');
        Contact cont2 = new Contact(FirstName='User', LastName='Two',                                     
                                    AccountId=acct.Id, My_ASCI_Role__c = 'Admin User', Training_Subscription_User__c = true);
        Contact cont3 = new Contact(FirstName='User', LastName='Three',                                     
                                    AccountId=acct.Id,    My_ASCI_Role__c = 'General User');
        Contact cont4 = new Contact(FirstName='User', LastName='Four',             
                                    AccountId=acct.Id,   My_ASCI_Role__c = 'Support User');
        insert cont1;
        insert cont2;
        insert cont3;
        insert cont4;
        
        
        Test.stopTest();
        
    }
    
}

Any help will be appreciated.
I have a checkbox field on the Contact object and would like to display all contacts that have that field selected to be displayed on the Account object.

What is the best way to accomplish this?
I'm getting the following error when Checking the challenge for the Enable Salesforce Knowledge component of the Knowledge Basics module in Trailhead even though everything is set up correctly according to the article. Knowledge is enabled, the language is set and the user has the appropriate permission. What am I missing?

User-added image
User-added image
User-added image
I'm working on a project where (already sent) emails should be saved to Salesforce and matched with the corresponding Salesforce contact.
Creating new Emails is rather straightforward. For example using the simple_salesforce python library my code looks like this:
 
from simple_salesforce import Salesforce

[…]

sf = Salesforce(instance_url=instance_url, session_id=session_id)
sf.EmailMessage.create(
    {'FromAddress': 'foo@example.com',
     'ToAddress': 'bar@example.com',
     'Subject': 'Email: Fancy Subject', 
     'TextBody': 'lorem ipsum dolor sit amet',  
     'Status': 2
    })

This successfully creates a new EmailMessage but the message is not matched to the contact (assuming bar@example.com is an exisiting contact in Salesfored). This can be seen in numerous places in the Salesforce UI. For example:
It is not part of the contact's activity history
When looking at the Email Message details, the section “Sender and Recipients” is empty
When creating new emails using the Salesforce UI, the association is done correctly. Comparing my EmailMessage objects from the ones generate by Salesforce there is one obvious difference: ActivityId is not set for my objects.
When I'm trying to set ActivityId to a matching Contact ID I receive a Malformed Request Exception INSUFFICIENT_ACCESS_OR_READONLY.

Am I missing something? Is it somehow possible to create those associations using the API?
Can someone help me identify what is chewing up our API calls? As of 3 days ago, we started hitting our 20K limit every day, and prior to that we'd barely hit 1000. I've turned off all our coded integrations, and we're still hitting 20k. I looked at the SF reports, but they only tell me # of API calls by user. How can I see what the API calls are and where they are coming from to help me track down where the leak is???
  • March 14, 2015
  • Like
  • 2