I am creating a new opportunity wizard to ensure that specific data is always entered when our sales reps create a new opportunity. As part of this effort, I've also over-written the lookup window for the Account lookup (leveraging this awesome post: Roll Your Own Salesforce "Lookup" Popup Window). On the second page of my wizard, after the user has selected an Account, I have them select the contacts and contact roles that will be associated with the opportunity. I want to over-write the lookup window for Contacts as well and limit the contacts displayed to only contacts that are associated with the Account the user selected in step one of the wizard.
My approach was to create a class that would be an extension for the Contact Lookup page and the controller for this page would be my custom controller that I'm using for the new opportunity wizard. My thinking here was that I need to be able to get access to the Account ID that the user selected in step one, so that I can use that to filter the contacts that I display in the contact lookup page.
However, I must not be understanding something basic here because I can't seem to get access to the custom controller's properties.
My assumption is that when the CustomContactLookupController is called that the createNewOpportunity controller is calling the constructor for CustomContactLookupController and passing a reference to itself? So, I should be able to access the properties of the controller class (e.g. I have a property "tempAcc" that I use to store the Account ID of the account the user selected in step one of the opportunity wizard).
However, when I look at the debug log it's showing that values are "null" in the constructor method for my CustomContactLookupController when I would expect them not to be? It's like it's creating a new instance of createNewOpportunity and passing that to the constructor?
Here's my controller class:
public with sharing class createNewOpportunity {
Public Opportunity opportunity {get; set;}
Public Account tempAcc {get; set;}
Private Final Id currentUserId {get; set;}
Public List<Opportunity> openOpps {get; set;}
Public Contact contact1 {get; set;}
Public Contact contact2 {get; set;}
Public Contact contact3 {get; set;}
Public Contact contact4 {get; set;}
Public Contact contact5 {get; set;}
Public OpportunityContactRole role1 {get; set;}
Public OpportunityContactRole role2 {get; set;}
Public OpportunityContactRole role3 {get; set;}
Public OpportunityContactRole role4 {get; set;}
Public OpportunityContactRole role5 {get; set;}
public createNewOpportunity()
{
opportunity = new Opportunity();
opportunity.StageName = 'Buyer Needs';
opportunity.OwnerId = UserInfo.getUserId();
opportunity.ForecastCategoryName = 'Omitted';
opportunity.Probability = 0;
tempAcc = new Account();
currentUserId = UserInfo.getUserId();
role1 = new OpportunityContactRole();
role1.opportunityId = opportunity.id;
role2 = new OpportunityContactRole();
role2.opportunityId = opportunity.id;
role3 = new OpportunityContactRole();
role3.opportunityId = opportunity.id;
role4 = new OpportunityContactRole();
role4.opportunityId = opportunity.id;
role5 = new OpportunityContactRole();
role5.opportunityId = opportunity.id;
System.debug('In Constructor for createNewOpportunity, tempAcc.Id: ' + tempAcc.Id);
System.debug('In Constructor for createNewOpportunity, opportunity.AccountId: ' + opportunity.AccountId);
}
public PageReference step1()
{
System.debug('In step1, tempAcc.Id: ' + tempAcc.Id);
System.debug('In step1, opportunity.AccountId: ' + opportunity.AccountId);
return Page.newOpportunityStep1;
}
public PageReference step2()
{
tempAcc = [SELECT Id, Name, countOpenOpportunities__c FROM Account WHERE Id =: opportunity.AccountId];
// Set the Opportunity name here based on what was set in step1
if (opportunity.Name == null)
{
//Set the opportunity name to a standard name
opportunity.Name = opportunity.Type + ' ' + opportunity.Service_Type__c + ' Program for ' + tempAcc.Name;
}
System.debug('In step2, tempAcc.Id: ' + tempAcc.Id);
System.debug('In step2, opportunity.AccountId: ' + opportunity.AccountId);
return Page.newOpportunityStep2;
}
public PageReference step3()
{
//Set the roles to the opportunity
if (role1.ContactId != null)
{
contact1 = [SELECT Id,Name,Title FROM Contact WHERE Id =: role1.ContactId];
}
if (role2.ContactId != null)
{
contact2 = [SELECT Id,Name,Title FROM Contact WHERE Id =: role2.ContactId];
}
if (role3.ContactId != null)
{
contact3 = [SELECT Id,Name,Title FROM Contact WHERE Id =: role3.ContactId];
}
if (role4.ContactId != null)
{
contact4 = [SELECT Id,Name,Title FROM Contact WHERE Id =: role4.ContactId];
}
if (role5.ContactId != null)
{
contact5 = [SELECT Id,Name,Title FROM Contact WHERE Id =: role5.ContactId];
}
return Page.newOpportunityStep3;
}
// This method cancels the wizard, and returns the user to the
// Opportunities tab
public PageReference cancel()
{
PageReference opportunityPage = new ApexPages.StandardController(opportunity).view();
opportunityPage.setRedirect(true);
return opportunityPage;
}
// This method performs the final save for all four objects, and
// then navigates the user to the detail page for the new
// opportunity.
public PageReference save()
{
opportunity.accountId = tempAcc.id;
insert opportunity;
if(role1.ContactId != null)
{
role1.opportunityId = opportunity.id;
insert role1;
}
if(role2.ContactId != null)
{
role2.opportunityId = opportunity.id;
insert role2;
}
if(role3.ContactId != null)
{
role3.opportunityId = opportunity.id;
insert role3;
}
if(role4.ContactId != null)
{
role4.opportunityId = opportunity.id;
insert role4;
}
if(role5.ContactId != null)
{
role5.opportunityId = opportunity.id;
insert role5;
}
// Finally, send the user to the detail page for
// the new opportunity.
PageReference opptyPage = new ApexPages.StandardController(opportunity).view();
opptyPage.setRedirect(true);
return opptyPage;
}
}
Here's my class for the custom contact lookup page:
public with sharing class CustomContactLookupController {
public Contact contact {get;set;} // new contact to create
public List<Contact> results {get;set;} // search results
public string searchString {get;set;} // search keyword
private final Id currentUserId; //logged in user's Id
private final Account myAcct;
private final createNewOpportunity myReference;
public CustomContactLookupController(createNewOpportunity myController) {
contact = new Contact();
this.myReference = myController;
System.debug('myReference.opportunity.AccountId: ' + myReference.opportunity.AccountId);
System.debug('myReference.tempAcc.Id: ' + myReference.tempAcc.Id);
System.debug('myReference.tempAcc.Name: ' + myReference.tempAcc.Name);
myAcct = myReference.tempAcc;
System.debug('myAcct Id: ' + myAcct.Id);
System.debug('myAcct Name: ' + myAcct.Name);
//this.myAcct = myController.getTheAccount();
//System.debug('Does myAcct have an ID now? ' + myAcct.Id);
//System.debug('Can I access a property on myController? ' + myController.tempAcc.Id);
currentUserId = UserInfo.getUserId();
// get the current search string
searchString = System.currentPageReference().getParameters().get('lksrch');
runSearch();
}
// performs the keyword search
public PageReference search()
{
runSearch();
return null;
}
// prepare the query and issue the search command
private void runSearch()
{
// TODO prepare query string for complex searches & prevent injections
results = performSearch(searchString);
}
// run the search and return the records found.
private List<Contact> performSearch(string searchString)
{
String soql = 'SELECT id, name FROM Contact';
if(searchString != '' && searchString != null)
{
soql = soql + ' WHERE name LIKE \'%' + searchString + '%\'';
soql = soql + ' AND OwnerId =: currentUserId';
soql = soql + ' AND AccountId =: myAcct.Id';
soql = soql + ' ORDER BY LastViewedDate DESC';
soql = soql + ' LIMIT 50';
} else
{
soql = soql + ' WHERE OwnerId =: currentUserId';
soql = soql + ' AND AccountId =: myAcct.Id';
soql = soql + ' ORDER BY LastViewedDate DESC';
soql = soql + ' LIMIT 50';
}
return database.query(soql);
}
// save the new contact record
public PageReference saveContact()
{
insert contact;
// reset the contact
contact = new Contact();
return null;
}
// used by the visualforce page to send the link to the right dom element
public string getFormTag()
{
return System.currentPageReference().getParameters().get('frm');
}
// used by the visualforce page to send the link to the right dom element for the text box
public string getTextBox()
{
return System.currentPageReference().getParameters().get('txt');
}
}
And then finally the top of my VF page for the custom contact lookup pop-up window looks like the following:
<apex:page controller="createNewOpportunity" extensions="CustomContactLookupController"
title="Search"
showHeader="false"
sideBar="false"
tabStyle="Contact"
id="pg">
...my VF page stuff...
</apex:page>
The error I'm getting currently is the following:
Visualforce Error
System.QueryException: Variable does not exist: myAcct.Id
Keep in mind that I'm a beginner (both as a developer and with apex) and still learning a lot of these concepts and there is a lot that still isn't completely clear to me.
Thanks for any help you can provide!
this.myAcct
fromCustomContactLookupController
(instead of from increateNewOpportunity
)?