function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Dave BerenatoDave Berenato 

Using a StandardController Extension to determine if a Record needs to be Created or Updated

I'm building out a link on the Lead to allow our salespeople to fill out an Application (Application__c) for a client. 

I want the URL to be linked to the Lead where:
 
https://corere--app--c.cs71.visual.force.com/apex/AssistanceApplication?acc={!Account__r.Id}

And then I'm writing a controller to basically determine if that attached Account has an existing Application to be updated or a new one to be created before page-load.
 
public class FAIRAssistanceApplication {

    public FAIRAssistanceApplication(){myParam = ApexPages.currentpage().getParameters().get('acc');}
    
    public String myParam { get; set; }    

    public List<Account> getAccount(){
        Map<String, Account> ExistingAppID = new Map<String, Account>();
        for (Account mapaccount : [Select FAIR_Assistance_Application__r.Id FROM Account WHERE Id = :myParam LIMIT 1])
        {ExistingAppID.put(mapaccount.FAIR_Assistance_Application__r.Id,mapaccount);}
        return ExistingAppID.values();}

    public String ExistingAppID { get; set; }   

    public void getAppId()
    {
        if(ExistingAppID != Null)
            
			{string AppId = ExistingAppID;}

        else{
        
        	Application__c NewApp = new Application__c();
            
        	NewApp.Property_Account__c = myParam;
        	NewApp.Name = 'Test';            
            Insert NewApp;

        	Account acc2  = [Select id,Name FROM Account WHERE Id = :myParam LIMIT 1];
			acc2.FAIR_Assistance_Application__c = NewApp.Id;
        	update acc2;
            
        	string AppId = NewApp.Id;
        }
    }
    
    public String AppId { get; set; }  
    
    public FAIRAssistanceApplication(ApexPages.StandardController controller) {
		ApexPages.currentPage().getParameters().put('id', AppId);
    }

}

The Account is linked to the Application by the Lookup field "Assistance_Application__c" and the Application is linked back to the Account with a Master-Detail field "Property_Account__c."

The Visualforce page loads and it will essentially be a stylized webform of <apex: inputField> for the StandardController "Application__c"

I loaded the Visualforce page and tested one save where no Application existed and one where it did exist and neither worked. They saved new Applications with only the fields in the InputFields being populated.
Waqar Hussain SFWaqar Hussain SF
Use application property on your VF page and use below code.
 
public class FAIRAssistanceApplication {
	
	public String myParam { get; set; }
    public FAIRAssistanceApplication(){
		myParam = ApexPages.currentpage().getParameters().get('acc');
	}
    
	public String ExistingAppID { get; set; }
    public List<Account> getAccount(){
        Map<String, Account> ExistingAppID = new Map<String, Account>();
        for (Account mapaccount : [Select FAIR_Assistance_Application__r.Id FROM Account WHERE Id = :myParam LIMIT 1])
        {ExistingAppID.put(mapaccount.FAIR_Assistance_Application__r.Id,mapaccount);}
        return ExistingAppID.values();
	}

       
	public Application__c Application {get; set;}
    public void getAppId()
    {
		Application = new Application__c();
		
		list<Application__c> apps = [Select Id,Name, Property_Account__c from Application__c where Property_Account__c = :myParam];
		
		if(apps.size() > 0){
			Application = app[0];
			AppId = app[0].Id;
			ExistingAppID = app[0].Id;
			
		}
        
		Application.Property_Account__c = myParam;
		Application.Name = 'Test';            
		upsert NewApp;

		Account acc2  = [Select id,Name FROM Account WHERE Id = :myParam LIMIT 1];
		acc2.FAIR_Assistance_Application__c = NewApp.Id;
		update acc2;
		
		string AppId = NewApp.Id;
        
    }
    
    public String AppId { get; set; }  
    
    public FAIRAssistanceApplication(ApexPages.StandardController controller) {
		ApexPages.currentPage().getParameters().put('id', AppId);
    }

}

 
Dave BerenatoDave Berenato
Hi Waqar! Thank you for the response. This might be a quick typo fix but I got a couple error messages with that code.
Is the "app" in line 25 a reference to the list "apps."

Also, just for my own understanding, what is Line 17 doing? That would help me write the Test Class for this Apex Class.

User-added image
 
Waqar Hussain SFWaqar Hussain SF
Ah my bad..

See updated code.
public class FAIRAssistanceApplication {
	
	public String myParam { get; set; }
    public FAIRAssistanceApplication(){
		myParam = ApexPages.currentpage().getParameters().get('acc');
		Application = new Application__c();
	}
    
	public String ExistingAppID { get; set; }
    public List<Account> getAccount(){
        Map<String, Account> ExistingAppID = new Map<String, Account>();
        for (Account mapaccount : [Select FAIR_Assistance_Application__r.Id FROM Account WHERE Id = :myParam LIMIT 1])
        {ExistingAppID.put(mapaccount.FAIR_Assistance_Application__r.Id,mapaccount);}
        return ExistingAppID.values();
	}

       
	public Application__c Application {get; set;}
    public void getAppId()
    {
		
		
		list<Application__c> apps = [Select Id,Name, Property_Account__c from Application__c where Property_Account__c = :myParam];
		
		if(apps.size() > 0){
			Application = apps[0];
			AppId = apps[0].Id;
			ExistingAppID = apps[0].Id;
			
		}
        
		Application.Property_Account__c = myParam;
		Application.Name = 'Test';            
		upsert Application;

		Account acc2  = [Select id,Name FROM Account WHERE Id = :myParam LIMIT 1];
		acc2.FAIR_Assistance_Application__c = Application.Id;
		update acc2;
		
		string AppId = Application.Id;
        
    }
    
    public String AppId { get; set; }  
    
    public FAIRAssistanceApplication(ApexPages.StandardController controller) {
		ApexPages.currentPage().getParameters().put('id', AppId);
    }

}

 
Dave BerenatoDave Berenato
Awesome! That was able to save.

Just to make sure I'm following this correctly, the idea is that the URL will have the "acc" where I can place an Account ID. If that Account ID has an Application attached, it will pull that existing one on page-load. If it does not, it will create and attach one on page-load and the user wouldn't know the difference unless there were already field values filled in.

For example, if I did a simple visualforce page such as the one below. I could use a URL such as:
 
https://corere--app--c.cs71.visual.force.com/apex/FAIRAssistanceApplication?acc=0014D000009r5gw

<apex:page showheader="false" standardController="Application__c" extensions="FAIRAssistanceApplication">

<body>
<apex:form >

    <p>{!Application__c.Property_Account__r.Name}</p>

    <p>{!Application__c.Name}</p>

    <p>Employer: <apex:inputField value="{!Application__c.Employer_Position_1__c}"/></p>

<apex:commandButton id="saveBtn" value="Save" action="{!save}" />

</apex:form>
</body>

</apex:page>

I tried this but none of the values load. If I click Save it saves a blank application with nothing but a Record ID as the Record Name.
Waqar Hussain SFWaqar Hussain SF
Hi Dave, 
 
Sorry for the late response. 

Yes, you are following correctly. But you will need to change the VF page code. See updated code.
<apex:page showheader="false" standardController="Application__c" extensions="FAIRAssistanceApplication">

<body>
<apex:form >

    <p>{!Application.Property_Account__r.Name}</p>

    <p>{!Application.Name}</p>

    <p>Employer: <apex:inputField value="{!Application.Employer_Position_1__c}"/></p>

<apex:commandButton id="saveBtn" value="Save" action="{!save}" />

</apex:form>
</body>

</apex:page>
 
public class FAIRAssistanceApplication {
	
	public String myParam { get; set; }
    public FAIRAssistanceApplication(){
		myParam = ApexPages.currentpage().getParameters().get('acc');
		Application = new Application__c();
	}
    
	public String ExistingAppID { get; set; }
    public List<Account> getAccount(){
        Map<String, Account> ExistingAppID = new Map<String, Account>();
        for (Account mapaccount : [Select FAIR_Assistance_Application__r.Id FROM Account WHERE Id = :myParam LIMIT 1])
        {ExistingAppID.put(mapaccount.FAIR_Assistance_Application__r.Id,mapaccount);}
        return ExistingAppID.values();
	}

       
	public Application__c Application {get; set;}
    public void getAppId()
    {
		
		
		list<Application__c> apps = [Select Id,Name, Property_Account__c,Property_Account__r.Name,Employer_Position_1__c  from Application__c where Property_Account__c = :myParam];
		
		if(apps.size() > 0){
			Application = apps[0];
			AppId = apps[0].Id;
			ExistingAppID = apps[0].Id;
			
		}
        
		Application.Property_Account__c = myParam;
		Application.Name = 'Test';            
		upsert Application;

		Account acc2  = [Select id,Name FROM Account WHERE Id = :myParam LIMIT 1];
		acc2.FAIR_Assistance_Application__c = Application.Id;
		update acc2;
		
		string AppId = Application.Id;
        
    }
    
    public String AppId { get; set; }  
    
    public FAIRAssistanceApplication(ApexPages.StandardController controller) {
		ApexPages.currentPage().getParameters().put('id', AppId);
    }

}

 
Dave BerenatoDave Berenato
Hi Waqar,

You've been insanely helpful with this, but this is still not working for me.

I went to the URL:
 
https://corere--app--c.cs71.visual.force.com/apex/FAIRAssistanceApplication2?acc=0014D000009r5gw

Where "FAIRAssistanceApplication2" is a direct copy and paste from the Visualforce you wrote above, and 0014D000009r5gw is a test Account.

Just from reading the code you've written, I believe the "acc" is supposed to query for that Account and if no Application is plugged into "FAIR Assistance Application" on the Account page, then it will create one and show both the name as "Test" and the Property Account as 0014D000009r5gw.

This is the only thing that loads. If I type anything into Employer and click save, no Application is created or updated.

User-added image

I don't want to take up too much of your time, I'm starting to wonder if I should find an alternative to this feature.
Waqar Hussain SFWaqar Hussain SF
Basically GetAppId function was not calling from the constructor. try below code
 
<apex:page showheader="false" standardController="Application__c" extensions="FAIRAssistanceApplication">

<body>
<apex:form >

    <p>{!Application.Property_Account__r.Name}</p>

    <p>{!Application.Name}</p>

    <p>Employer: <apex:inputField value="{!Application.Employer_Position_1__c}"/></p>

<apex:commandButton id="saveBtn" value="Save" action="{!save}" />

</apex:form>
</body>

</apex:page>
 
public class FAIRAssistanceApplication {
	
	public String myParam { get; set; }
    public FAIRAssistanceApplication(){
		myParam = ApexPages.currentpage().getParameters().get('acc');
		Application = new Application__c();
		getAppId();
	}
    
	public String ExistingAppID { get; set; }
    public List<Account> getAccount(){
        Map<String, Account> ExistingAppID = new Map<String, Account>();
        for (Account mapaccount : [Select FAIR_Assistance_Application__r.Id FROM Account WHERE Id = :myParam LIMIT 1])
        {ExistingAppID.put(mapaccount.FAIR_Assistance_Application__r.Id,mapaccount);}
        return ExistingAppID.values();
	}

       
	public Application__c Application {get; set;}
    public void getAppId()
    {
		
		
		list<Application__c> apps = [Select Id,Name, Property_Account__c,Property_Account__r.Name,Employer_Position_1__c  from Application__c where Property_Account__c = :myParam];
		
		if(apps.size() > 0){
			Application = apps[0];
			AppId = apps[0].Id;
			ExistingAppID = apps[0].Id;
			
		}
        
		Application.Property_Account__c = myParam;
		Application.Name = 'Test';            
		upsert Application;

		Account acc2  = [Select id,Name FROM Account WHERE Id = :myParam LIMIT 1];
		acc2.FAIR_Assistance_Application__c = Application.Id;
		update acc2;
		
		string AppId = Application.Id;
        
    }
    
    public String AppId { get; set; }  
    
    public FAIRAssistanceApplication(ApexPages.StandardController controller) {
		ApexPages.currentPage().getParameters().put('id', AppId);
		myParam = ApexPages.currentpage().getParameters().get('acc');
		Application = new Application__c();
		getAppId();
    }

}

 
Dave BerenatoDave Berenato
Let's try it this way.

I wrote a Visual Workflow that takes "var_AccountID" from the URL and uses that to make an Application__c and save it. 

I can have the Visualforce page determine if the URL is either "?var_AccountID={!Account.Id}" or "?ID={Application__r.Id}" so that it can either run the flow or show the Application depending on what's needed.

Now all I need is for the Flow to redirect to the final app using the "var_AppID" that the flow creates.
 
public class FAIRAssistanceApplication {

     public FAIRAssistanceApplication (ApexPages.StandardController controller) {
    }
    public ID getAccId = System.currentPagereference().getParameters().get('var_AccountID');
    
    
    public Flow.Interview.NewFAIRAppAuto NewAppFlow{get;set;}
    public String getAccountId(){ return getAccId; }

    public ID AppId = NewAppFlow.var_AppID;
    
    public PageReference getAppId(){
        
        if(NewAppFlow != null) AppId = NewAppFlow.var_AppID;

        PageReference send = new PageReference('/' + NewAppFlow.var_AppID);
        send.setRedirect(true);
        return send;

    }
    
}
 
<apex:page showheader="false" standardController="Application__c" extensions="FAIRAssistanceApplication">



<apex:pageblock rendered="{!IF(ISBLANK(Application__c.Property_Account__c),TRUE,FALSE)}">
    <flow:interview name="NewFAIRAppAuto" interview="{!NewAppFlow}" finishLocation="{!AppId}')}">
    </flow:interview>
</apex:pageblock>




<apex:form rendered="{!IF(NOT(ISBLANK(Application__c.Property_Account__c)),TRUE,FALSE)}">
    <p>{!Application__c.Property_Account__r.Name}</p>
    <p>{!Application__c.Name}</p>
    <p>Employer: <apex:inputField value="{!Application__c.Employer_Position_1__c}"/></p>

<apex:commandButton id="saveBtn" value="Save" action="{!save}" onclick="window.parent.location.href='thankyou'" oncomplete="!URLFOR('https://corere--c.na50.visual.force.com/apex/thankyou')}"/>

</apex:form>

</apex:page>