• sfadmin 182
  • NEWBIE
  • 30 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 4
    Replies
Hello all,

I have a requirement to notify an external system after every dml event for Leads, Accounts, Contacts and AccountContacRelations. The external system does not want to consume any SFDC api so it is up to my SFDC system to send all the notifications for each dml event on the said objects. I have triggers that call a method that creates the JSON package to send to the external system and initially was sending them through a future call, the callout is bulkified so at least a large number of any of the objects will be handled.

There is a problem here though, first many updates to different objects can potentially go over the maximum number of queued future calls. Second, i cant ensure the order of execution, so for example on a lead convert there will be a lead update notification, an account insert notification, a contact insert and an accountContacRelation insert notification. Plus since i have to update record types on a couple of these records, that causes extra dmls and extra notifications. Since the order of execution of the future methods cant be guaranteed, this has caused incorrect sequence of callouts to the external system.

I am unsure how to successfully approach this? I would much rather send one large JSON package with all the notifications included, but then how do i add the trigger.new records from all the triggers to a list<object> then call the callout method since i dont know which will be the last trigger to run or related class executed from those triggers? 

Alternatively, is there a way to run the callouts synchronously? Any help/feedback will be greatly appreciated.

 
So I created a custom lookup to provide a search functionality for a contact insert/edit table. The idea is that the user can "load"an existing contact instead of creating a duplicate in the system. When the lookup page is opened, the user does a search for a contact and when they click on the contact they want, the page calls the parent page's closeLookupPopup() method which would close the popup page. The method calls an actionfunction after doing the closing of the popup but the loadContact() actionfunction is either not getting called or the action method within it. I am not sure what is wrong with this so reaching out to someone who can help.
main VF pg:
<tbody> <apex:actionFunction action="{!loadCompContactInfo}" name="loadContact" reRender="contCompPanel,guarCompPanel,msgs,msgsBtn" > </apex:actionFunction> <apex:repeat var="cont" value="{!editCompanyWrapper.companycontactWrappers}"> <tr> <td> <apex:inputtext value="{!cont.contactId}" id="targetId" /> <apex:inputText value="{!cont.contactName}" id="targetName" > <apex:actionSupport event="onchange"> <apex:param assignTo="{!contWrpId}" name="wrpId" value="{!cont.ContactId}"></apex:param> </apex:actionSupport> </apex:inputText> <a href="#" onclick="openLookupPopup('{!$Component.targetName}', '{!$Component.targetId}'); return false">Search Contact</a> </td> <td class="slds-truncate"> <apex:inputField styleclass="slds-input" value="{!cont.contact.FirstName}"/> </td> <td class="slds-truncate"> <apex:inputField styleclass="slds-input" value="{!cont.contact.LastName}"/> </td> <td class="slds-truncate"> <apex:inputField styleclass="slds-input" value="{!cont.contact.Email}"/> </td> <td class="slds-truncate"> <apex:inputField styleclass="slds-input" value="{!cont.contact.MobilePhone}"/> </td> <td class="slds-truncate"><apex:inputCheckbox style="zoom: 150%" value="{!cont.acr.Designated_Signer__c}" /></td> <td class="slds-truncate"><apex:inputText value="{!cont.RoutingOrder}" /></td> <td class="slds-truncate"><apex:inputCheckbox style="zoom: 150%" value="{!cont.contact.Active__c}" /></td> <td class="slds-truncate"> <apex:actionRegion > <apex:commandButton action="{!deleteContact}" title="Remove Contact" value="Remove" styleclass="slds-button slds-button_destructive delBtn" reRender="contCompPanel,msgs,msgsBtn" rendered="{!cont.isNew == true}" > <apex:param value="{!cont.contact.Id}" assignTo="{!contId}" name="contactId" /> </apex:commandButton> </apex:actionRegion> </td> </tr> </apex:repeat> </tbody> //javascript in vf page var newWin=null; function openLookupPopup(name, id){ var url="/apex/LookupContactPopup?namefield=" + name + "&idfield=" + id; newWin=window.open(url, 'Popup','height=500,width=600,left=100,top=100,resizable=no,scrollbars=yes,toolbar=no,status=no'); if (window.focus) { newWin.focus(); } return false; } function closeLookupPopup(){ if (null!=newWin) { console.log('### closeLookpupPopup'); newWin.close(); console.log('### closeLookpupPopup after close'); loadContact(); console.log('### closeLookpupPopup after loadContact'); } }

//javascript in vf page 
var newWin=null; 
function openLookupPopup(name, id){ 
    var url="/apex/LookupContactPopup?namefield=" + name + "&idfield=" + id; 
    newWin=window.open(url, 'Popup','height=500,width=600,left=100,top=100,resizable=no,scrollbars=yes,toolbar=no,status=no'); 
    if (window.focus) { newWin.focus(); } 
    return false; 
} 
function closeLookupPopup(){ 
    if (null!=newWin) { 
        console.log('### closeLookpupPopup'); 
        newWin.close(); 
        console.log('### closeLookpupPopup after close'); 
        loadContact(); 
        console.log('### closeLookpupPopup after loadContact'); 
    } 
}//if I put loadContact() before newWin.close() then the popup doesn't close and the actionfunction is not fired, otherwise the close popoup works but not the actionfunction

controller methods in use:
public Id contWrpId  {get;set;}
//I've tried this methods return type as PageReference and also void but both dont work
public void loadCompContactInfo (){
    //if there is a selected contact, load the ACR and Contact info onto the GUaranteeContactWrapper
    system.debug('[loadCompContactInfo] contWrpId:' + contWrpId);
    system.debug('[loadCompContactInfo] companycontactWrappers:' + editCompanyWrapper.companycontactWrappers);
    if(contWrpId != null)
    for(GuaranteeContactWrapper gcw: editCompanyWrapper.companycontactWrappers){
        if(contWrpId  == gcw.contact.id){
            Contact sfcont = [Select id, AccountId, FirstName, LastName, Email, MobilePhone From Contact Where Id = :contWrpId limit 1];
            gcw.contact = sfCont;
            gcw.acr.ContactId = sfCont.id; 
        }
    }   
}
popup Vf pg:
<apex:page controller="LookupContactPopupController" sidebar="false" showheader="false">
<script language="javascript">
   window.onload = new function() { 
      // bring popup window to front
      window.focus(); 
      var ele=document.getElementById('{!$Component.form.block.section.query}');
      if (ele)
      {
         ele.focus();
      }
   }
   
   function fillIn(name, id){
      var winMain=window.opener;
      if (null==winMain)
      {
         winMain=window.parent.opener;
      }
      var ele=winMain.document.getElementById('{!$CurrentPage.parameters.namefield}');
      ele.value=name;
      ele=winMain.document.getElementById('{!$CurrentPage.parameters.idfield}');
      ele.value=id;
      CloseWindow();
   }

   function CloseWindow(){
      var winMain=window.opener;
      if (null==winMain)
      {
         winMain=window.parent.opener;
      }
       
      winMain.closeLookupPopup();
   }
</script>

  <apex:messages />
  <apex:form id="form">  
        
     <div style="width 100%">
        <apex:pageBlock title="Lookup" id="block">
           
          <apex:pageBlockSection id="section">
              Enter search text and click Go<br/>
              <apex:inputText value="{!query}" id="query"/> 
              <apex:commandButton value="Go" action="{!runQuery}"/>
          </apex:pageBlockSection>
        </apex:pageBlock>

        <apex:pageBlock >
          <apex:pageBlockSection columns="1">
              <apex:pageBlockTable value="{!contacts}" var="contact">
                <apex:column headerValue="Name">
                  <apex:outputLink value="#" onclick="fillIn('{!contact.Name}', '{!contact.id}')">{!Contact.Name}</apex:outputLink>       
                </apex:column>
                <apex:column headerValue="Street" value="{!contact.FirstName}"/>
                <apex:column headerValue="City" value="{!contact.LastName}"/>
                <apex:column headerValue="Account" value="{!contact.Account.Name}"/>
                <apex:column headerValue="Email" value="{!contact.Email}"/>
                <apex:column headerValue="Mobile Phone" value="{!contact.MobilePhone}"/>
              </apex:pageBlockTable>    
          </apex:pageBlockSection>
        </apex:pageBlock>
        <button type="button" onclick="CloseWindow();">Close Window</button>
     </div>
   </apex:form>
</apex:page>
popup controller:
public with sharing class LookupContactPopupController {
    public String query {get; set;}
    public List<Contact> contacts {get; set;}
    
    public PageReference runQuery()
    {
        List<List<Contact>> searchResults=[FIND :query IN ALL FIELDS RETURNING contact (id, accountId, Account.Name, firstname, lastName, name, email, mobilephone)];
        contacts=searchResults[0];
        return null;
    }
}


 
I have a wrapper object which nests a couple of custom sobjects within it, one of these is an account. When I reference the account in a table in visualforce the data gets loaded just fine, but when I make changes to it seems like the values are not getting set in the controller record:

(These will all be snippets of a larger page/class but all relevant code has been provided)

visualforce page: (i tried both inputField and inputText but it still doesnt work)
<apex:pageBlock rendered="{!showCompanyEditSection}">   
                <apex:sectionHeader title="Company Edit" subtitle="{!if(editCompanyWrapper.isNew =true,'New Account', editCompanyAccount.Name)}"/>
                <apex:pageBlockSection>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Name" value="{!editCompanyAccount.name}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Full Legal Name" value="{!editCompanyAccount.full_Legal_Name__c}"/>
                    <apex:inputtext  styleclass="slds-input slds-size_1-of-2" label="ABN" value="{!editCompanyAccount.abn__c}"/>
                    <apex:inputField  styleclass="slds-input slds-size_1-of-2" label="ACN" value="{!editCompanyAccount.acn__c}"/>
                    <apex:inputField  styleclass="slds-input slds-size_1-of-2" label="ACN" value="{!editCompanyAccount.type}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Street" value="{!editCompanyAccount.billingStreet}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="City" value="{!editCompanyAccount.billingCity}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-4" label="State" value="{!editCompanyAccount.billingState}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-4" label="Postal Code" value="{!editCompanyAccount.billingPostalCode}"/>
                </apex:pageBlockSection>

controller: (the first debug is showing no change to the fields in the nested account (guaranteeAccount)
// first validate account data
        system.debug('### [saveEditCompany] editCompanyWrapper: ' + editCompanyWrapper);
        if(validateAccountData(editCompanyWrapper.guaranteeAccount) == false){
            ApexPages.Message msgError = new ApexPages.Message(ApexPages.Severity.ERROR,'All Account information must be completed before saving.');
            ApexPages.addMessage(msgError);
            return null;
        }

    private boolean validateAccountData (Account pAcc){
        if(pAcc.Name == null || pAcc.Full_Legal_Name__c == null || pAcc.BillingStreet == null || pAcc.BillingCity == null || pAcc.BillingState == null || pAcc.BillingPostalCode == null){
            return false;
        }
        else return true;
    }
wrapper class:
/*COMPANY GUARANTEE WRAPPER CLASS*/
    public class GuaranteeAccountWrapper {
        public boolean                 isNew                        {get;set;}
        public Boolean                 active                       {get;set;}
        public Company_Guarantee__c    companyGuarantee             {get;set;}
        public Account                 guaranteeAccount             {get;set;}
        public GuaranteeContactWrapper[] companycontactWrappers     {get;set;}
    }

    public  GuaranteeAccountWrapper             editCompanyWrapper      {get{ return companyGuaranteeWrappersMap.get(accId);}set;}
    public  Account                             editCompanyAccount      { get{ return companyGuaranteeWrappersMap.get(accId).guaranteeAccount;} set;}



I dont know what is going on, why arent values getting passed back to the controller.
 
Hello,

I have a visualforce page that i use to generate an excel file which is then sent as an attachment in an email. The problem im having is that one of the columns whenever there is a leading 0 it gets stripped on the output excel file but this 0 is a valid character and i want to keep it. I have tried adding &quot; to the value tag and also using outputtext but if a quote is added (both single and double) then the exported file will contain that quote which is also not a valid.

This is the line causing issues: <apex:column headerValue="DR BSB" value="{!invBSB}"/>
This is the VF page:
<apex:page controller="fundingUI_Excel_Controller" contentType="application/vnd.ms-excel#PPAY.xls" cache="true">
	<apex:dataTable var="dt" value="{!dtxns}">
		<apex:column headerValue="DR ACLR Code"/>
		<apex:column headerValue="CR ACLR Code"/>
		<apex:column headerValue="DR BSB" value="{!invBSB}"/>
		<apex:column headerValue="DR Account" value="{!invBankAccNum}"/>
		<apex:column headerValue="Payee Name" value="{!dt.Account_Full_legal_Name__c}"/>
		<apex:column headerValue="Payee Amount" value="{!dt.Disbursal_Transaction_Amount__c}"/>
		<apex:column headerValue="CR BSB" value="{!dt.Borrower_Bank_BSB__c}"/>
		<apex:column headerValue="CR Account" value="{!dt.Borrower_Bank_Account_Number__c}"/>
		<apex:column headerValue="Payment Type" value="{!paymType}"/>
		<apex:column headerValue="Narration">
			<apex:outputText>Banjo Ref {!dt.Banjo_Loan_No__c}</apex:outputText>
		</apex:column>
		<apex:column headerValue="Payment Date" >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Trade Date" >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Settlement Date"  >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Asset Code"/>
		<apex:column headerValue="Units"/>
		<apex:column headerValue="Brokerage"/>
		<apex:column headerValue="Broker"/>
		<apex:column headerValue="Contract Note"/>
		<apex:column headerValue="Expense Code">
			<apex:outputText value="TRANSFER"/>
		</apex:column>
		<apex:column headerValue="Transaction type">
			<apex:outputText value="FO"/>
		</apex:column>
	</apex:dataTable>
</apex:page>


 
Hello all,

I have a requirement to notify an external system after every dml event for Leads, Accounts, Contacts and AccountContacRelations. The external system does not want to consume any SFDC api so it is up to my SFDC system to send all the notifications for each dml event on the said objects. I have triggers that call a method that creates the JSON package to send to the external system and initially was sending them through a future call, the callout is bulkified so at least a large number of any of the objects will be handled.

There is a problem here though, first many updates to different objects can potentially go over the maximum number of queued future calls. Second, i cant ensure the order of execution, so for example on a lead convert there will be a lead update notification, an account insert notification, a contact insert and an accountContacRelation insert notification. Plus since i have to update record types on a couple of these records, that causes extra dmls and extra notifications. Since the order of execution of the future methods cant be guaranteed, this has caused incorrect sequence of callouts to the external system.

I am unsure how to successfully approach this? I would much rather send one large JSON package with all the notifications included, but then how do i add the trigger.new records from all the triggers to a list<object> then call the callout method since i dont know which will be the last trigger to run or related class executed from those triggers? 

Alternatively, is there a way to run the callouts synchronously? Any help/feedback will be greatly appreciated.

 
I have a wrapper object which nests a couple of custom sobjects within it, one of these is an account. When I reference the account in a table in visualforce the data gets loaded just fine, but when I make changes to it seems like the values are not getting set in the controller record:

(These will all be snippets of a larger page/class but all relevant code has been provided)

visualforce page: (i tried both inputField and inputText but it still doesnt work)
<apex:pageBlock rendered="{!showCompanyEditSection}">   
                <apex:sectionHeader title="Company Edit" subtitle="{!if(editCompanyWrapper.isNew =true,'New Account', editCompanyAccount.Name)}"/>
                <apex:pageBlockSection>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Name" value="{!editCompanyAccount.name}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Full Legal Name" value="{!editCompanyAccount.full_Legal_Name__c}"/>
                    <apex:inputtext  styleclass="slds-input slds-size_1-of-2" label="ABN" value="{!editCompanyAccount.abn__c}"/>
                    <apex:inputField  styleclass="slds-input slds-size_1-of-2" label="ACN" value="{!editCompanyAccount.acn__c}"/>
                    <apex:inputField  styleclass="slds-input slds-size_1-of-2" label="ACN" value="{!editCompanyAccount.type}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="Street" value="{!editCompanyAccount.billingStreet}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-1" label="City" value="{!editCompanyAccount.billingCity}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-4" label="State" value="{!editCompanyAccount.billingState}"/>
                    <apex:inputField styleclass="slds-input slds-size_1-of-4" label="Postal Code" value="{!editCompanyAccount.billingPostalCode}"/>
                </apex:pageBlockSection>

controller: (the first debug is showing no change to the fields in the nested account (guaranteeAccount)
// first validate account data
        system.debug('### [saveEditCompany] editCompanyWrapper: ' + editCompanyWrapper);
        if(validateAccountData(editCompanyWrapper.guaranteeAccount) == false){
            ApexPages.Message msgError = new ApexPages.Message(ApexPages.Severity.ERROR,'All Account information must be completed before saving.');
            ApexPages.addMessage(msgError);
            return null;
        }

    private boolean validateAccountData (Account pAcc){
        if(pAcc.Name == null || pAcc.Full_Legal_Name__c == null || pAcc.BillingStreet == null || pAcc.BillingCity == null || pAcc.BillingState == null || pAcc.BillingPostalCode == null){
            return false;
        }
        else return true;
    }
wrapper class:
/*COMPANY GUARANTEE WRAPPER CLASS*/
    public class GuaranteeAccountWrapper {
        public boolean                 isNew                        {get;set;}
        public Boolean                 active                       {get;set;}
        public Company_Guarantee__c    companyGuarantee             {get;set;}
        public Account                 guaranteeAccount             {get;set;}
        public GuaranteeContactWrapper[] companycontactWrappers     {get;set;}
    }

    public  GuaranteeAccountWrapper             editCompanyWrapper      {get{ return companyGuaranteeWrappersMap.get(accId);}set;}
    public  Account                             editCompanyAccount      { get{ return companyGuaranteeWrappersMap.get(accId).guaranteeAccount;} set;}



I dont know what is going on, why arent values getting passed back to the controller.
 
Hello,

I have a visualforce page that i use to generate an excel file which is then sent as an attachment in an email. The problem im having is that one of the columns whenever there is a leading 0 it gets stripped on the output excel file but this 0 is a valid character and i want to keep it. I have tried adding &quot; to the value tag and also using outputtext but if a quote is added (both single and double) then the exported file will contain that quote which is also not a valid.

This is the line causing issues: <apex:column headerValue="DR BSB" value="{!invBSB}"/>
This is the VF page:
<apex:page controller="fundingUI_Excel_Controller" contentType="application/vnd.ms-excel#PPAY.xls" cache="true">
	<apex:dataTable var="dt" value="{!dtxns}">
		<apex:column headerValue="DR ACLR Code"/>
		<apex:column headerValue="CR ACLR Code"/>
		<apex:column headerValue="DR BSB" value="{!invBSB}"/>
		<apex:column headerValue="DR Account" value="{!invBankAccNum}"/>
		<apex:column headerValue="Payee Name" value="{!dt.Account_Full_legal_Name__c}"/>
		<apex:column headerValue="Payee Amount" value="{!dt.Disbursal_Transaction_Amount__c}"/>
		<apex:column headerValue="CR BSB" value="{!dt.Borrower_Bank_BSB__c}"/>
		<apex:column headerValue="CR Account" value="{!dt.Borrower_Bank_Account_Number__c}"/>
		<apex:column headerValue="Payment Type" value="{!paymType}"/>
		<apex:column headerValue="Narration">
			<apex:outputText>Banjo Ref {!dt.Banjo_Loan_No__c}</apex:outputText>
		</apex:column>
		<apex:column headerValue="Payment Date" >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Trade Date" >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Settlement Date"  >
			<apex:outputText value="{0, date, dd'/'MM'/'YYYY}">
    			<apex:param value="{!TODAY()}" /> 
			</apex:outputText>
		</apex:column>
		<apex:column headerValue="Asset Code"/>
		<apex:column headerValue="Units"/>
		<apex:column headerValue="Brokerage"/>
		<apex:column headerValue="Broker"/>
		<apex:column headerValue="Contract Note"/>
		<apex:column headerValue="Expense Code">
			<apex:outputText value="TRANSFER"/>
		</apex:column>
		<apex:column headerValue="Transaction type">
			<apex:outputText value="FO"/>
		</apex:column>
	</apex:dataTable>
</apex:page>


 
Hi 
I am doing Superbadge Advanced Apex Specialist. I have completed 7 steps successfully. I am doing development in developer console. 
When I am clicking on check challenge on step 8 I am getting below error
User-added image

As all other chalenges are already completed how can i fix the issue because i am unable to retake those steps again (I am not getting any option to check chalange for completed chalenges). I am also not having previous code as I am doing development in developer console.

I am ready to retake all changes again but how can I do it without creating other trailhead account.