-
ChatterFeed
-
5Best Answers
-
4Likes Received
-
0Likes Given
-
69Questions
-
66Replies
trigger to create an activity when an opportunity reaches a certain stage
I am trying to write a trigger that will create an activity when an opportunity reaches a certain stage. I want the activity to be assigned to the owner of the opportunity and to be related to the opportunity, but when I try to assign values to the appropriate fields I get 'Field is not writeable' errors. Here is the code with these fields commented out:
--------------------------------------------------------------------------------
trigger CreateActivityAfterClosedWon on Opportunity (after insert, after update) {
List<Task> NewTasks = new List<Task>();
for (Opportunity opp: Trigger.new){
if (opp.StageName == '100 - Closed Won - Booked'){
NewTasks.add(new Task(
ActivityDate = Date.today(),
//What = opp.Id,
//Owner = opp.Owner,
Status = 'Closed',
Activity_Type__c = 'Project Won',
Priority = 'Normal',
Subject = opp.Name));
}
}
insert NewTasks;
}
--------------------------------------------------------------------------------------------
With these fields commented out, the trigger runs in the sand box and creates activities, but the activities are not related to any object and are assigned to me (because the code ran under my account).
Can anybody suggest a solution?
Thanks & Regards,
Jeff
- jsymonds24
- October 07, 2013
- Like
- 0
- Continue reading or reply
Right justify in apex:pageblocktable with extra padding
Thanks!
.number{ text-align: right; } .ruiColumnWidth{ width: 15%; } .ruiMonthEven{ background: #F5F5F5; } .ruiMonthOdd{ } <apex:pageBlockTable value="{!ruiWrappers}" var="wrapper" cellpadding="5"> <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number"> <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/> </apex:column> <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}"> <apex:outputText value="{!wrapper.ruiProbability}"/> </apex:column> </apex:pageBlockTable>
.number{ text-align: right; padding-right: 5px; } .ruiColumnWidth{ width: 15%; } .ruiMonthEven{ background: #F5F5F5; } .ruiMonthOdd{ } <apex:pageBlockTable value="{!ruiWrappers}" var="wrapper"> <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number"> <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/> </apex:column> <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}"> <apex:outputText value="{!wrapper.ruiProbability}"/> </apex:column> </apex:pageBlockTable>
- mgodsey
- April 09, 2015
- Like
- 0
- Continue reading or reply
javascript popup with salesforce dependent picklists
I know this is possible using a custom button which re-directs the user to a Visualforce page (so not quite a pop-up) and uses apex:inputFields. However, does anyone know if this would be possible using a custom button that executes JavaScript on click? I'm just not sure if it would be too much overkill to build the dependent picklists on this pop-up page or if there is an easy way to grab the information from the Salesforce fields.
I'm not really looking for the code here, just general thoughs on if this approach is even possible/worth considering.
Thanks!
- mgodsey
- February 19, 2015
- Like
- 0
- Continue reading or reply
Overriding Opportunity Tab with VF page
<apex:page standardController="Opportunity" extensions="OpportunityTabExtension" readOnly="true" tabStyle="Opportunity"> <apex:sectionHeader title="{!$ObjectType.Opportunity.LabelPlural}" subtitle="Home"/> <apex:pageBlock title="Recently Viewed"> <apex:pageBlockTable value="{!recentOpps}" var="opp"> <apex:column headerValue="Opportunity"> <apex:outputLink title="Opportunity" value="/{!opp.Id}"> <apex:outputfield value="{!opp.Name}"/> </apex:outputLink> </apex:column> <apex:column title="{!$ObjectType.Opportunity.Fields.OwnerId.Label}" value="{!opp.OwnerId}"/> <apex:column title="{!$ObjectType.Opportunity.Fields.StageName.Label}" value="{!opp.StageName}"/> </apex:pageBlockTable> </apex:pageBlock> <apex:pageBlock title="List Views"> <apex:ListViews type="Opportunity"/> </apex:pageBlock> </apex:page>
- mgodsey
- November 10, 2014
- Like
- 0
- Continue reading or reply
CommandButton action not called after javascript remoting
If I click the 'Copy Opportunity without Media Plan' button, both confirmation pop-up alerts are displayed to the user, but nothing happens when they click 'OK.' If I click the 'Copy Opportunity without Media Plan 2' button, which does not have the remote action, the first confirmation pop-up is displayed, and when they click 'OK' the Opportunity clones.
Will javascript remoting not work in this scenario? It's my first time using it, so I don't understand it fully. Do I need to use action:function instead?
Thanks for the help!
Snippet Visualforce Page:
<script type="text/javascript"> //confirm that they want to clone the Opportuntiy function confirmOppOnlyClone(){ return confirm('Do you want to copy this Opportunity only?'); } //check if other opportunities have been cloned from this one function duplicateOppsCheck(){ var oppId = "{!opportunity.Id}"; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.OpportunityExtension.duplicateOppsCheck}', oppId, function(result, event) { if(event.status){ if (result != null){ return confirm(result); } } } ); } </script> <apex:form > <apex:sectionHeader subtitle="{!opportunity.Name}" title="Opportunity"/> <apex:pageMessages /> <apex:pageBlock > <apex:pageBlockButtons > <apex:commandButton value="Copy Opportunity without Media Plan" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;if(!duplicateOppsCheck()) return false"/> <apex:commandButton value="Copy Opportunity without Media Plan 2" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;"/>
Snippet of Controller Extension:
@RemoteAction public static String duplicateOppsCheck (String opportunityId){ String confirmMessage = 'There is an existing Opportunity that has been copied from this Opportunity. Please confirm that it is not a duplicate.\n\n'; Boolean returnConfirmMessage = false; //if there are any existing opportunities that were copied from the current one, add their names and urls to the confirmation message for(Opportunity opp : [SELECT Id, Name FROM Opportunity WHERE ClonedFrom__c =: opportunityId]){ confirmMessage += 'Name: '+opp.Name +'\n'; confirmMessage += System.URL.getSalesforceBaseURL().toExternalForm()+'/'+opp.id + '\n\n'; returnConfirmMessage = true; } if(returnConfirmMessage){ return confirmMessage; } return null; }
- mgodsey
- October 28, 2014
- Like
- 0
- Continue reading or reply
System.SObjectException: Invalid field AccountFromId
Account acct = UnitTestFactory.makeAccount(); Account agencyAcct = UnitTestFactory.makeAccount(); agencyAcct.Type = 'Agency'; update agencyAcct; Partner pa = new Partner(); pa.AccountFromId = acct.Id; pa.AccountToId = agencyAcct.Id; insert pa;
- mgodsey
- September 17, 2014
- Like
- 0
- Continue reading or reply
Prepopulating Contact Role on New Opportunity
conid={!Contact.Id}
Now we are trying to completely override the standard 'New' Opportunity page with a Visualforce page. Is there anyway to default the Opportunity Contact Role if I am passing in the contact Id through a custom button? Or will I have to store this Id somewhere, and then write a trigger after insert to create the Opportunity Contact Role?
Below is some of the extension code for the VF page. Thanks for any guidance!
public with sharing class OpportunityNewExtension {
private Opportunity currentOpp;
//following Ids are passed in through the custom button
public Id accountId;
public Id contactId;
public OpportunityNewExtension(ApexPages.StandardController controller) {
//get information about the opportunity and related account
currentOpp = (Opportunity)controller.getRecord();
accountId = ApexPages.currentPage().getParameters().get('accountId');
Account acct = [SELECT Type, BillingCountry FROM Account WHERE Id=: accountId];
//set default values for required fields
currentOpp.StageName = Status.Omit;
currentOpp.Name = 'Default'; //will be updated via workflow on save
currentOpp.CloseDate = System.today()+30;
- mgodsey
- August 25, 2014
- Like
- 0
- Continue reading or reply
Issue with immediate="true" in command button
<apex:column headerValue="Add Test"> <apex:actionStatus id="addStatus" > <apex:facet name="stop" > <apex:commandButton value="Select" action="{!addToQuoteLineItemWrappers}" reRender="selected,errors" immediate="true" image="{!$Resource.GreenPlus}" status="addStatus"> <apex:param value="{!product.Id}" assignTo="{!toSelectId}" name="toSelectId"/> </apex:commandButton> </apex:facet> <apex:facet name="start"> <apex:commandButton value="Adding - See Below" disabled="true" status="addStatus" /> </apex:facet> </apex:actionStatus> </apex:column>
- mgodsey
- July 02, 2014
- Like
- 0
- Continue reading or reply
Test Coverage - 'all tests 0%' but individual methods have percentage (36% and 52%)
1) I run the test in the developer console. The Test Run log is not actually showing up unless I completely close the developer console and then re-open it.
2) After running the test (it succeeds), in the overall code coverage box, the class says 100%
3) I double click on the class name in the overall code coverage box and it goes to 0%
4) When I look at the drop down of tests for that class, it shows me the following:
All Tests 0%
Test_QuoteLineITemEntryExtension.testSaveMethods 52%
Test_QuoteLineItemEntryExtension.testControllerWithParameters 36%
Why would it be showing 0% for all tests if individual methods provide coverage? Also, there is no red/blue highlighting in the class to show me what is or is not covered.
Has anyone run into this before? It's driving me crazy! Would be happy to post my test class if that helps. Thanks!
- mgodsey
- April 04, 2014
- Like
- 0
- Continue reading or reply
Add Red "Required" Line conditionally
<apex:column headerValue="{!$ObjectType.QuoteLineItem.Fields.AdServer__c.Label}" rendered="{!s.qLine.PricebookEntry.Product2.DisplayAdServer__c}" style="vertical-align:top">
<apex:outputPanel >
<div class="requiredInput">
<div class="requiredBlock"></div>
<apex:selectList value="{!s.qLine.AdServer__c}" required="{!s.qLine.PricebookEntry.Product2.RequiredAdServer__c}" multiselect="false" size="1">
<apex:selectOptions value="{!s.adServerOptions}"/>
</apex:selectList>
</div>
</apex:outputPanel>
</apex:column>
- mgodsey
- March 24, 2014
- Like
- 0
- Continue reading or reply
Hiring: Force Engineer for Quantcast, in San Francisco
We use Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.
Responsibilities
- Build flexible, scalable and robust technical solutions to meet dynamic needs of fast-growing and fast-paced business
- Design, development and deploy complex solutions in our Salesforce instance
- Build and expand integrations to Salesforce
- Conduct peer code reviews
- Analyze and develop solutions to end-user support issues
If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it. Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=ot6DYfwU
- mgodsey
- March 21, 2014
- Like
- 1
- Continue reading or reply
Hiring: Senior Force Solutions Engineer for Quantcast, in San Francisco
Quantcast uses Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.
Responsibilities
- Build flexible, scalable and robust technical solutions to meet dynamic needs of fastgrowing and fastpaced business
- Lead Salesforce solution design, development and deployment activities
- Drive adoption of development methodology best practices
- Evangelize and faciliate the Force platform across the engineering organization
- Mentor Salesforce developers in methodology and advanced development skills
If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it. Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=oQpiXfwe
- mgodsey
- March 21, 2014
- Like
- 0
- Continue reading or reply
VF version of record type selection page
Here is the VF page:
<apex:page controller="NewMediaPlanOverride">
<apex:form >
<apex:pageMessages />
<p style="font-size:20px"> What type of Media Plan are you creating?</p>
<apex:commandButton action="{!newProposal}" value="Proposal"/>
<apex:commandButton value="Insertion Order"/>
</apex:form>
</apex:page>
The code works when I have it written this way:
public with sharing class NewMediaPlanOverride {
public String oppId {get; set;}
public NewMediaPlanOverride() {
oppId = ApexPages.currentPage().getParameters().get('oppId');
}
public PageReference newProposal() {
Savepoint sp = Database.setSavepoint();
try{
Quote newQuote = new Quote();
Recordtype rt = [SELECT Name FROM RecordType WHERE Name = 'Proposal' and SObjectType = 'Quote' Limit 1];
String recTypeId = rt.Id;
//build the URL that the user will be redirected to
//Quote is a standard object so the prefix is consistant across orgs
String nextPage = '/0Q0/e?oppid=' + oppId + '&RecordType=' + recTypeId + '&retURL=%2F'+oppId + '&ent=Quote';
PageReference pageRef = new PageReference(nextPage);
return pageRef;
} catch(Exception e){
Database.rollback(sp);
ApexPages.addMessages(e);
return null;
}
}
However, since I'm going to have to repeat the redirect logic for different record types, I've tried to put it in its own method. Now when I click the button, it just stays on the same page instead of redirecting.
public with sharing class NewMediaPlanOverride {
public String oppId {get; set;}
public NewMediaPlanOverride() {
oppId = ApexPages.currentPage().getParameters().get('oppId');
}
public void newProposal() {
String recTypeId = getRecordTypeId('Proposal');
newQuote(recTypeId);
}
public PageReference newQuote(String recTypeId){
Savepoint sp = Database.setSavepoint();
try{
Quote newQuote = new Quote();
//build the URL that the user will be redirected to
//Quote is a standard object so the prefix is consistant across orgs
String nextPage = '/0Q0/e?oppid=' + oppId + '&RecordType=' + recTypeId + '&retURL=%2F'+oppId + '&ent=Quote';
PageReference pageRef = new PageReference(nextPage);
System.debug('[MF] nextPage: ' + nextPage);
System.debug('[MF] pageRef' + pageRef);
return pageRef;
} catch(Exception e){
System.debug('[MF] is there an error?' +e);
Database.rollback(sp);
ApexPages.addMessages(e);
return null;
}
}
public String getRecordTypeID(String type){
RecordType rt = [SELECT Name FROM RecordType WHERE Name =:type AND SObjectType = 'Quote' Limit 1];
String recTypeId = rt.Id;
return recTypeId;
}
}
Can anyone help me figure out why the second version of this code is not working? Here are the debug statements:
DEBUG|[MF] nextPage: /0Q0/e?oppid=006S00000070yVM&RecordType=012S00000004fibIAA&retURL=%2F006S00000070yVM&ent=Quote
DEBUG|[MF] pageRefSystem.PageReference[/0Q0/e?ent=Quote&oppid=006S00000070yVM&RecordType=012S00000004fibIAA&retURL=%2F006S00000070yVM]
Thank you!
- mgodsey
- March 17, 2014
- Like
- 0
- Continue reading or reply
VF page to replace standard record type selection page
I have two record types for the standard Quote object. Rather than having the user use the standard record type selection page when they click "New Quote", I want them redirected to a VF page. On this VF page there will be two buttons - a button called "Proposal" to create a Quote with record type A, and one called "Insertion Order" to create a Quote with record type B.
I've tried reading the previous posts about this, but most are from a few years ago and don't seem to offer working solutions.
I've created a page and controller extension, but it is only working if I hardcode in the Opportunity ID. Is there going to be any way for me to get this Opp ID programmatically? Thank you!
VF Page
<apex:page standardController="Quote" extensions="NewMediaPlanExtension" recordSetVar="quotes">
<apex:form >
<p style="font-size:25px"> What type of Media Plan are you creating?</p>
<br/>
<apex:commandButton action="{!newProposal}" value="Proposal"/>
</apex:form>
</apex:page>
Controller
public with sharing class NewMediaPlanExtension {
public ApexPages.StandardSetController sController{get;set;}
public NewMediaPlanExtension(ApexPages.StandardSetController controller){
sController = controller;
}
public PageReference newProposal(){
String prefix = Quote.SObjectType.getDescribe().getKeyPrefix();
String param = 'oppid=006S00000070yVM&RecordType=012S00000004fib';
return new PageReference('/'+prefix+'/e?noovverride=1&' + param);
}
}
- mgodsey
- March 10, 2014
- Like
- 0
- Continue reading or reply
Top align field in column in apex:pageBlockTable
- mgodsey
- March 06, 2014
- Like
- 2
- Continue reading or reply
Assigning a territory to a test user in unit test
- mgodsey
- January 29, 2014
- Like
- 0
- Continue reading or reply
Hiring: Lead Force.com Developer for Quantcast, a Digital Advertising Company in San Francisco
This is an opportunity to combine your software engineering capabilities with deep Force.com knowledge to dramatically evolve the platform that people throughout Quantcast rely on and has major implications for our productivity and growth.
A little bit about us: Quantcast is a digital advertising company specialized in audience measurement and real-time advertising. As the pioneer of direct audience measurement in 2006, Quantcast has today the most in-depth understanding of digital audiences across the web, allowing marketers and publishers to make the smartest choices as they buy and sell the most effective targeted advertising on the market. For more information about Quantcast, please visit: https://www.quantcast.com/word
If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it. Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=oQpiXfwe
- mgodsey
- January 22, 2014
- Like
- 0
- Continue reading or reply
use calendar widget without current date link
<apex:inputField value="{!s.CampaignSTARTDate__c}" style="width:70px" required="true" showdatePicker="false" />
When I then added the type="date" attribute, I got the following error message:
Attribute 'type' on component <apex:inputField> in '/apex/quoteLineItemEntryOption4' requires HTML docType version 5.0 or higher in quoteLineItemEntryOption4 at line 183 column 138
I'm not sure of the implications of changing the docType to version 5.0 and I don't like the way the field looks with that type, so I'd prefer not to do it this way. Does anyone know any other workarounds?
Thanks!
- mgodsey
- January 13, 2014
- Like
- 0
- Continue reading or reply
Passing picklist value to controller
When I change the value of TestInventoryType__c I get the alert that the doSearch() function is called, but my second alert comes back null. I would really appreciate if someone could tell me why this is coming back null, and if there is a better way to do this. How could I go about binding the value selected in the Inventory Type picklist to a property in the controller? I need all of this to happen when the picklist value changes without hitting any sort of command button. Thank you!
Here is a snippet of the VF page. The two most relevant lines are bolded:
<apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">
<table width="100%" border="0">
<tr>
<td width="275" valign="top">
<!-------This is the Search by picklist section-------------------------->
<apex:pageBlock title="Search" mode="edit" id="criteria">
<script type="text/javascript">
function doSearch() {
alert('doSearch function');
alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL
searchServer(
document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex].value,
document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex].value,
document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex].value,
document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value
);
}
</script>
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
<apex:param name="creativeFamily" value="" />
<apex:param name="creativeTypes" value="" />
<apex:param name="pricingModel" value="" />
<apex:param name="targetingOption" value="" />
</apex:actionFunction>
<apex:pageBlockSection columns="1">
<apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>
- mgodsey
- January 13, 2014
- Like
- 0
- Continue reading or reply
Dynamic Search/VF page not re-rendering
Any feedback is much appreciated, thank you!!
Here is my controller class:
public with sharing class quoteLineItemEntryExtensionOption4 {
public Quote theQuote {get;set;}
public Pricebook2 theBook {get;set;}
private Boolean forcePricebookSelection = false;
//the soql without the order and limit
private String soql {get;set;}
//the collection of products to display
public List<priceBookEntry> availableProducts {get;set;}
//the current sort direction. defaults to asc
public String sortDir{
get{
if (sortDir == null){
sortDir = 'asc';
}
return sortDir;
}
set;
}
// the current field to sort by. defaults to Quote name
public String sortField {
get{
if (sortField == null){
sortField = 'Quote';
}
return sortField;
}
set;
}
// format the soql for display on the visualforce page
public String debugSoql {
get{
return soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/;
}
set;
}
// init the controller and display some sample data when the page loads
public quoteLineItemEntryExtensionOption4(ApexPages.StandardController controller){
//get information about the Quote being worked on
theQuote = database.query('select Id, Pricebook2Id,Pricebook2.Name,CurrencyISOCode from Quote where Id = \'' + controller.getRecord().Id + '\' limit 1');
//Check if the Opp has a pricebook associated yet
if(theQuote.Pricebook2Id == null){
Pricebook2[] activepbs = [select ID, Name FROM Pricebook2 WHERE isActive = true limit 2];
if(activepbs.size() == 2){
forcePriceBookSelection = true;
theBook = new Pricebook2();
} else {
theBook = activepbs[0];
}
}
else{
theBook = theQuote.Pricebook2;
}
//this soql just shows the initial results when page is loaded
soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Product2.CreativeFamily__c != null and Pricebook2Id = \'' + theBook.Id + '\'';
runQuery();
}
// toggles the sorting of query from asc<-->desc
public void toggleSort() {
// simply toggle the direction
sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
// run the query again
runQuery();
}
// runs the actual query
public void runQuery() {
try {
availableProducts = Database.query(soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/);
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops! There are no results for this search'));
}
}
// runs the search with parameters passed via Javascript
public PageReference runSearch() {
String creativeFamily = Apexpages.currentPage().getParameters().get('creativeFamily');
String creativeTypes = Apexpages.currentPage().getParameters().get('creativeTypes');
String pricingModel = Apexpages.currentPage().getParameters().get('pricingModel');
String targetingOptions = Apexpages.currentPage().getParameters().get('targetingOptions');
soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';
if (!creativeFamily.equals(''))
soql += ' and Product2.CreativeFamily__c LIKE (\''+creativeFamily+'\')';
if (!creativeTypes.equals(''))
soql += ' and Product2.CreativeType__c LIKE (\''+creativeTypes+'\')';
if (!pricingModel.equals(''))
soql += ' and Product2.pricingModel__c LIKE (\''+pricingModel+'\')';
if (!targetingOptions.equals(''))
soql += ' and Product2.TargetingOptions__c LIKE (\''+targetingOptions+'\')';
// run the query again
System.debug('[MF] running the query from runSearch method' + soql);
runQuery();
return null;
}
//use apex describe to build the picklist values for Creative Family
public List<String> creativeFamily{
get{
if(creativeFamily == null){
creativeFamily = new List<String>();
Schema.DescribeFieldResult field = Product2.CreativeFamily__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
creativeFamily.add(f.getLabel());
}
}
return creativeFamily;
}
set;
}
//use apex describe to build the picklist values for Creative Type
public List<String> creativeType{
get{
if(creativeType == null){
creativeType = new List<String>();
Schema.DescribeFieldResult field = Product2.creativeType__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
creativeType.add(f.getLabel());
}
}
return creativeType;
}
set;
}
//use apex describe to build the picklist values for Pricing Model
public List<String> pricingModel{
get{
if(pricingModel == null){
pricingModel = new List<String>();
Schema.DescribeFieldResult field = Product2.pricingModel__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
pricingModel.add(f.getLabel());
}
}
return pricingModel;
}
set;
}
//use apex describe to build the picklist values
public List<String> targetingOptions{
get{
if(targetingOptions == null){
targetingOptions = new List<String>();
Schema.DescribeFieldResult field = Product2.TargetingOptions__c.getDescribe();
for(Schema.PicklistEntry f : field.getPickListValues()){
targetingOptions.add(f.getLabel());
}
}
return targetingOptions;
}
set;
}
}
Here is my VF page:
<apex:page standardController="Quote" extensions="quoteLineItemEntryExtensionOption4" sidebar="false">
<apex:form >
<apex:pageMessages id="errors" />
<apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">
<table width="100%" border="0">
<tr>
<td width="200" valign="top">
<apex:pageBlock title="Search" mode="edit" id="criteria">
<script type="text/javascript">
function doSearch() {
searchServer(
document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex.]value,
document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex.]value,
document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex.]value,
document.getElementById("targetingOptions").options[document.getElementById("targetingOptions").selectedIndex].value
);
}
</script>
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
<apex:param name="creativeFamily" value="" />
<apex:param name="creativeTypes" value="" />
<apex:param name="pricingModel" value="" />
<apex:param name="targetingOptions" value="" />
</apex:actionFunction>
<table cellpadding="2" cellspacing="2">
<tr>
<td style="font-weight:bold;">Creative Family<br/>
<select id ="creativeFamily" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!creativeFamily}" var="cFamily">
<option value="{!cFamily}">{!cFamily}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Creative Type<br/>
<select id ="creativeType" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!creativeType}" var="cType">
<option value="{!cType}">{!cType}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Pricing Model<br/>
<select id ="Pricing Model" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!pricingModel}" var="pm">
<option value="{!pm}">{!pm}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Targeting Options<br/>
<select id="targetingOptions" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!targetingOptions}" var="targeting">
<option value="{!targeting}">{!targeting}</option>
</apex:repeat>
</select>
</td>
</tr>
</table>
</apex:pageBlock>
</td>
<td valign="top">
<apex:pageBlock title="Available Products To Add" mode="edit" id="results">
<apex:pageBlockTable value="{!availableProducts}" var="product">
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Product Name" action="{!toggleSort}" reRender="results,debug">
<apex:param name="sortfield" value="Product2.Name" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.Name}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Creative Family" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.creativeFamily__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.CreativeFamily__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Creative Type" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.creativeType__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.CreativeType__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Pricing Model" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.pricingModel__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.PricingModel__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Targeting Options" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.targetingOptions" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.TargetingOptions__c}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</td>
</tr>
</table>
<apex:pageBlock title="Selected Products">
</apex:pageBlock>
<apex:pageBlock title="Debug - SOQL" id="debug">
<apex:outputText value="{!debugSoql}" />
</apex:pageBlock>
</apex:pageBlock>
</apex:form>
</apex:page>
- mgodsey
- December 31, 2014
- Like
- 0
- Continue reading or reply
Improving Code Efficiency - Getting field for specific Opportunity from field name
I have a class that compares the values of fields on two different Opportunities, and if they have different values some logic occurs. Right now I am using a long list of "IF" statements, but I've been tasked to make it more efficient. Here is a sample of the code right now:
//check each field to see if has a different value from the cloned from opp. //I'm doing this one field at a time, because they have to be added to the Whats Changed field in a specific (page layout) order //also, a few fields will be treated differently in terms of what goes into the What's Changed field if(opp.ClientStrategist__c != clonedFromOpp.ClientStrategist__c){ Changes.add(createChangeStringNoChangeDisplay(Opportunity.ClientStrategist__c, fieldToLabel, 'Opportunity')); } if(opp.AccountId != clonedFromOpp.AccountId){ Changes.add(createChangeStringNoChangeDisplay(Opportunity.AccountId, fieldToLabel, 'Opportunity')); } if(opp.Buyer__c != clonedFromOpp.Buyer__c){ Changes.add(createChangeStringDisplayChanges(Opportunity.Buyer__c, fieldToLabel, clonedFromOpp.Buyer__c)); } if(opp.Agency__c != clonedFromOpp.Agency__c){ Changes.add(createChangeStringNoChangeDisplay(Opportunity.Agency__c, fieldToLabel, 'Opportunity')); }
I want to try and change it so that rather than creating an IF statement for each field, I use a for loop to check each one. Something along the lines of:
List<sObjectField> fieldsList = new List<sObjectField>{ Opportunity.ClientStrategist__c, Opportunity.AccountId, Opportunity.Buyer__c }; for(String field: fieldsList){ if(opp.field != clonedFromOpp.field){ Changes.add(creativeChangeStringDisplayChanges(field, fieldToLabel, clonedFromOpp.field, 'Opportunity') } }
The issue I'm having is that in some parts I need the sObject Field name (i.e. 'Opportunity.ClientStrategist__c) and in other places I need the variable (i.e. 'opp.ClientStrategist__c).
Is there any way I can use the sObject Field name to get the variable? For example, in java I think we chould use something like
opp.getField(field). Is there something similar in Apex?
Thank you in advance for any help!
- mgodsey
- October 07, 2013
- Like
- 0
- Continue reading or reply
Hiring: Force Engineer for Quantcast, in San Francisco
We use Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.
Responsibilities
- Build flexible, scalable and robust technical solutions to meet dynamic needs of fast-growing and fast-paced business
- Design, development and deploy complex solutions in our Salesforce instance
- Build and expand integrations to Salesforce
- Conduct peer code reviews
- Analyze and develop solutions to end-user support issues
If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it. Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=ot6DYfwU
- mgodsey
- March 21, 2014
- Like
- 1
- Continue reading or reply
Top align field in column in apex:pageBlockTable
- mgodsey
- March 06, 2014
- Like
- 2
- Continue reading or reply
Conditionally hide field on page layout
We have a formula field, GrossBudget__c, that should only be displayed on the layout if a certain condition is true. I don't want to create a visualforce page to replace the entire standard layout. Is it possible to achieve this by creating a visualforce page for just GrossBudget__c and add in a condition that it should only be visible under a certain condition? And then we can just place that mini visualforce page on the standard layout?
If anyone can let me know if this is even possible or point me in the direction of any documentation or blog posts on this it would be greatly appreciated!
- mgodsey
- January 28, 2013
- Like
- 1
- Continue reading or reply
Right justify in apex:pageblocktable with extra padding
Thanks!
.number{ text-align: right; } .ruiColumnWidth{ width: 15%; } .ruiMonthEven{ background: #F5F5F5; } .ruiMonthOdd{ } <apex:pageBlockTable value="{!ruiWrappers}" var="wrapper" cellpadding="5"> <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number"> <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/> </apex:column> <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}"> <apex:outputText value="{!wrapper.ruiProbability}"/> </apex:column> </apex:pageBlockTable>
.number{ text-align: right; padding-right: 5px; } .ruiColumnWidth{ width: 15%; } .ruiMonthEven{ background: #F5F5F5; } .ruiMonthOdd{ } <apex:pageBlockTable value="{!ruiWrappers}" var="wrapper"> <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number"> <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/> </apex:column> <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}"> <apex:outputText value="{!wrapper.ruiProbability}"/> </apex:column> </apex:pageBlockTable>
- mgodsey
- April 09, 2015
- Like
- 0
- Continue reading or reply
javascript popup with salesforce dependent picklists
I know this is possible using a custom button which re-directs the user to a Visualforce page (so not quite a pop-up) and uses apex:inputFields. However, does anyone know if this would be possible using a custom button that executes JavaScript on click? I'm just not sure if it would be too much overkill to build the dependent picklists on this pop-up page or if there is an easy way to grab the information from the Salesforce fields.
I'm not really looking for the code here, just general thoughs on if this approach is even possible/worth considering.
Thanks!
- mgodsey
- February 19, 2015
- Like
- 0
- Continue reading or reply
CommandButton action not called after javascript remoting
If I click the 'Copy Opportunity without Media Plan' button, both confirmation pop-up alerts are displayed to the user, but nothing happens when they click 'OK.' If I click the 'Copy Opportunity without Media Plan 2' button, which does not have the remote action, the first confirmation pop-up is displayed, and when they click 'OK' the Opportunity clones.
Will javascript remoting not work in this scenario? It's my first time using it, so I don't understand it fully. Do I need to use action:function instead?
Thanks for the help!
Snippet Visualforce Page:
<script type="text/javascript"> //confirm that they want to clone the Opportuntiy function confirmOppOnlyClone(){ return confirm('Do you want to copy this Opportunity only?'); } //check if other opportunities have been cloned from this one function duplicateOppsCheck(){ var oppId = "{!opportunity.Id}"; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.OpportunityExtension.duplicateOppsCheck}', oppId, function(result, event) { if(event.status){ if (result != null){ return confirm(result); } } } ); } </script> <apex:form > <apex:sectionHeader subtitle="{!opportunity.Name}" title="Opportunity"/> <apex:pageMessages /> <apex:pageBlock > <apex:pageBlockButtons > <apex:commandButton value="Copy Opportunity without Media Plan" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;if(!duplicateOppsCheck()) return false"/> <apex:commandButton value="Copy Opportunity without Media Plan 2" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;"/>
Snippet of Controller Extension:
@RemoteAction public static String duplicateOppsCheck (String opportunityId){ String confirmMessage = 'There is an existing Opportunity that has been copied from this Opportunity. Please confirm that it is not a duplicate.\n\n'; Boolean returnConfirmMessage = false; //if there are any existing opportunities that were copied from the current one, add their names and urls to the confirmation message for(Opportunity opp : [SELECT Id, Name FROM Opportunity WHERE ClonedFrom__c =: opportunityId]){ confirmMessage += 'Name: '+opp.Name +'\n'; confirmMessage += System.URL.getSalesforceBaseURL().toExternalForm()+'/'+opp.id + '\n\n'; returnConfirmMessage = true; } if(returnConfirmMessage){ return confirmMessage; } return null; }
- mgodsey
- October 28, 2014
- Like
- 0
- Continue reading or reply
Test Coverage - 'all tests 0%' but individual methods have percentage (36% and 52%)
1) I run the test in the developer console. The Test Run log is not actually showing up unless I completely close the developer console and then re-open it.
2) After running the test (it succeeds), in the overall code coverage box, the class says 100%
3) I double click on the class name in the overall code coverage box and it goes to 0%
4) When I look at the drop down of tests for that class, it shows me the following:
All Tests 0%
Test_QuoteLineITemEntryExtension.testSaveMethods 52%
Test_QuoteLineItemEntryExtension.testControllerWithParameters 36%
Why would it be showing 0% for all tests if individual methods provide coverage? Also, there is no red/blue highlighting in the class to show me what is or is not covered.
Has anyone run into this before? It's driving me crazy! Would be happy to post my test class if that helps. Thanks!
- mgodsey
- April 04, 2014
- Like
- 0
- Continue reading or reply
Top align field in column in apex:pageBlockTable
- mgodsey
- March 06, 2014
- Like
- 2
- Continue reading or reply
Assigning a territory to a test user in unit test
- mgodsey
- January 29, 2014
- Like
- 0
- Continue reading or reply
use calendar widget without current date link
<apex:inputField value="{!s.CampaignSTARTDate__c}" style="width:70px" required="true" showdatePicker="false" />
When I then added the type="date" attribute, I got the following error message:
Attribute 'type' on component <apex:inputField> in '/apex/quoteLineItemEntryOption4' requires HTML docType version 5.0 or higher in quoteLineItemEntryOption4 at line 183 column 138
I'm not sure of the implications of changing the docType to version 5.0 and I don't like the way the field looks with that type, so I'd prefer not to do it this way. Does anyone know any other workarounds?
Thanks!
- mgodsey
- January 13, 2014
- Like
- 0
- Continue reading or reply
Passing picklist value to controller
When I change the value of TestInventoryType__c I get the alert that the doSearch() function is called, but my second alert comes back null. I would really appreciate if someone could tell me why this is coming back null, and if there is a better way to do this. How could I go about binding the value selected in the Inventory Type picklist to a property in the controller? I need all of this to happen when the picklist value changes without hitting any sort of command button. Thank you!
Here is a snippet of the VF page. The two most relevant lines are bolded:
<apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">
<table width="100%" border="0">
<tr>
<td width="275" valign="top">
<!-------This is the Search by picklist section-------------------------->
<apex:pageBlock title="Search" mode="edit" id="criteria">
<script type="text/javascript">
function doSearch() {
alert('doSearch function');
alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL
searchServer(
document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex].value,
document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex].value,
document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex].value,
document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value
);
}
</script>
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
<apex:param name="creativeFamily" value="" />
<apex:param name="creativeTypes" value="" />
<apex:param name="pricingModel" value="" />
<apex:param name="targetingOption" value="" />
</apex:actionFunction>
<apex:pageBlockSection columns="1">
<apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>
- mgodsey
- January 13, 2014
- Like
- 0
- Continue reading or reply
Dynamic Search/VF page not re-rendering
Any feedback is much appreciated, thank you!!
Here is my controller class:
public with sharing class quoteLineItemEntryExtensionOption4 {
public Quote theQuote {get;set;}
public Pricebook2 theBook {get;set;}
private Boolean forcePricebookSelection = false;
//the soql without the order and limit
private String soql {get;set;}
//the collection of products to display
public List<priceBookEntry> availableProducts {get;set;}
//the current sort direction. defaults to asc
public String sortDir{
get{
if (sortDir == null){
sortDir = 'asc';
}
return sortDir;
}
set;
}
// the current field to sort by. defaults to Quote name
public String sortField {
get{
if (sortField == null){
sortField = 'Quote';
}
return sortField;
}
set;
}
// format the soql for display on the visualforce page
public String debugSoql {
get{
return soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/;
}
set;
}
// init the controller and display some sample data when the page loads
public quoteLineItemEntryExtensionOption4(ApexPages.StandardController controller){
//get information about the Quote being worked on
theQuote = database.query('select Id, Pricebook2Id,Pricebook2.Name,CurrencyISOCode from Quote where Id = \'' + controller.getRecord().Id + '\' limit 1');
//Check if the Opp has a pricebook associated yet
if(theQuote.Pricebook2Id == null){
Pricebook2[] activepbs = [select ID, Name FROM Pricebook2 WHERE isActive = true limit 2];
if(activepbs.size() == 2){
forcePriceBookSelection = true;
theBook = new Pricebook2();
} else {
theBook = activepbs[0];
}
}
else{
theBook = theQuote.Pricebook2;
}
//this soql just shows the initial results when page is loaded
soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Product2.CreativeFamily__c != null and Pricebook2Id = \'' + theBook.Id + '\'';
runQuery();
}
// toggles the sorting of query from asc<-->desc
public void toggleSort() {
// simply toggle the direction
sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
// run the query again
runQuery();
}
// runs the actual query
public void runQuery() {
try {
availableProducts = Database.query(soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/);
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops! There are no results for this search'));
}
}
// runs the search with parameters passed via Javascript
public PageReference runSearch() {
String creativeFamily = Apexpages.currentPage().getParameters().get('creativeFamily');
String creativeTypes = Apexpages.currentPage().getParameters().get('creativeTypes');
String pricingModel = Apexpages.currentPage().getParameters().get('pricingModel');
String targetingOptions = Apexpages.currentPage().getParameters().get('targetingOptions');
soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';
if (!creativeFamily.equals(''))
soql += ' and Product2.CreativeFamily__c LIKE (\''+creativeFamily+'\')';
if (!creativeTypes.equals(''))
soql += ' and Product2.CreativeType__c LIKE (\''+creativeTypes+'\')';
if (!pricingModel.equals(''))
soql += ' and Product2.pricingModel__c LIKE (\''+pricingModel+'\')';
if (!targetingOptions.equals(''))
soql += ' and Product2.TargetingOptions__c LIKE (\''+targetingOptions+'\')';
// run the query again
System.debug('[MF] running the query from runSearch method' + soql);
runQuery();
return null;
}
//use apex describe to build the picklist values for Creative Family
public List<String> creativeFamily{
get{
if(creativeFamily == null){
creativeFamily = new List<String>();
Schema.DescribeFieldResult field = Product2.CreativeFamily__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
creativeFamily.add(f.getLabel());
}
}
return creativeFamily;
}
set;
}
//use apex describe to build the picklist values for Creative Type
public List<String> creativeType{
get{
if(creativeType == null){
creativeType = new List<String>();
Schema.DescribeFieldResult field = Product2.creativeType__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
creativeType.add(f.getLabel());
}
}
return creativeType;
}
set;
}
//use apex describe to build the picklist values for Pricing Model
public List<String> pricingModel{
get{
if(pricingModel == null){
pricingModel = new List<String>();
Schema.DescribeFieldResult field = Product2.pricingModel__c.getDescribe();
for(Schema.Picklistentry f : field.getPickListValues()){
pricingModel.add(f.getLabel());
}
}
return pricingModel;
}
set;
}
//use apex describe to build the picklist values
public List<String> targetingOptions{
get{
if(targetingOptions == null){
targetingOptions = new List<String>();
Schema.DescribeFieldResult field = Product2.TargetingOptions__c.getDescribe();
for(Schema.PicklistEntry f : field.getPickListValues()){
targetingOptions.add(f.getLabel());
}
}
return targetingOptions;
}
set;
}
}
Here is my VF page:
<apex:page standardController="Quote" extensions="quoteLineItemEntryExtensionOption4" sidebar="false">
<apex:form >
<apex:pageMessages id="errors" />
<apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">
<table width="100%" border="0">
<tr>
<td width="200" valign="top">
<apex:pageBlock title="Search" mode="edit" id="criteria">
<script type="text/javascript">
function doSearch() {
searchServer(
document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex.]value,
document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex.]value,
document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex.]value,
document.getElementById("targetingOptions").options[document.getElementById("targetingOptions").selectedIndex].value
);
}
</script>
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
<apex:param name="creativeFamily" value="" />
<apex:param name="creativeTypes" value="" />
<apex:param name="pricingModel" value="" />
<apex:param name="targetingOptions" value="" />
</apex:actionFunction>
<table cellpadding="2" cellspacing="2">
<tr>
<td style="font-weight:bold;">Creative Family<br/>
<select id ="creativeFamily" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!creativeFamily}" var="cFamily">
<option value="{!cFamily}">{!cFamily}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Creative Type<br/>
<select id ="creativeType" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!creativeType}" var="cType">
<option value="{!cType}">{!cType}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Pricing Model<br/>
<select id ="Pricing Model" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!pricingModel}" var="pm">
<option value="{!pm}">{!pm}</option>
</apex:repeat>
</select>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Targeting Options<br/>
<select id="targetingOptions" onchange="doSearch();">
<option value=""></option>
<apex:repeat value="{!targetingOptions}" var="targeting">
<option value="{!targeting}">{!targeting}</option>
</apex:repeat>
</select>
</td>
</tr>
</table>
</apex:pageBlock>
</td>
<td valign="top">
<apex:pageBlock title="Available Products To Add" mode="edit" id="results">
<apex:pageBlockTable value="{!availableProducts}" var="product">
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Product Name" action="{!toggleSort}" reRender="results,debug">
<apex:param name="sortfield" value="Product2.Name" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.Name}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Creative Family" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.creativeFamily__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.CreativeFamily__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Creative Type" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.creativeType__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.CreativeType__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Pricing Model" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.pricingModel__c" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.PricingModel__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Targeting Options" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Product2.targetingOptions" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!product.Product2.TargetingOptions__c}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</td>
</tr>
</table>
<apex:pageBlock title="Selected Products">
</apex:pageBlock>
<apex:pageBlock title="Debug - SOQL" id="debug">
<apex:outputText value="{!debugSoql}" />
</apex:pageBlock>
</apex:pageBlock>
</apex:form>
</apex:page>
- mgodsey
- December 31, 2014
- Like
- 0
- Continue reading or reply
trigger to create an activity when an opportunity reaches a certain stage
I am trying to write a trigger that will create an activity when an opportunity reaches a certain stage. I want the activity to be assigned to the owner of the opportunity and to be related to the opportunity, but when I try to assign values to the appropriate fields I get 'Field is not writeable' errors. Here is the code with these fields commented out:
--------------------------------------------------------------------------------
trigger CreateActivityAfterClosedWon on Opportunity (after insert, after update) {
List<Task> NewTasks = new List<Task>();
for (Opportunity opp: Trigger.new){
if (opp.StageName == '100 - Closed Won - Booked'){
NewTasks.add(new Task(
ActivityDate = Date.today(),
//What = opp.Id,
//Owner = opp.Owner,
Status = 'Closed',
Activity_Type__c = 'Project Won',
Priority = 'Normal',
Subject = opp.Name));
}
}
insert NewTasks;
}
--------------------------------------------------------------------------------------------
With these fields commented out, the trigger runs in the sand box and creates activities, but the activities are not related to any object and are assigned to me (because the code ran under my account).
Can anybody suggest a solution?
Thanks & Regards,
Jeff
- jsymonds24
- October 07, 2013
- Like
- 0
- Continue reading or reply
Cloning Opp Team Members with their Access Level
I am using a standard controller extension to custom clone Opportunities. It will allow Opportunities to be cloned with their Opportunity Teams (among other objects). However, I'm having trouble getting the access level for the team member to clone as well. From looking at the community boards I know that I need to insert an OpportunityShare record as well, but that hasn't helped. Even if the team member had Read/Write access on the original Opp, on the clone they just have Read access.
Can anyone take a peek at my code below and let me know where I've gone wrong? Thanks!!
public class OpportunityCloneExtension{ //Variable to hold current record Opportunity currentRecord; //Standard constructor method public OpportunityCloneExtension(ApexPages.StandardController controller){ currentRecord = (Opportunity)controller.getRecord(); } public PageReference cloneRecord(){ //Variable to hold the new record Opportunity newRecord; Savepoint sp = Database.setSavepoint(); try{ //------Cloning the Opportunity----------- //get all the creatable fields from the object so they can be cloned String oppSOQL = CSUtils.getCreatableFieldsSOQL('Opportunity', 'id=\''+currentRecord.id+'\''); //query for the current Opportunity and clone it, replacing a few field values first currentRecord = (Opportunity)Database.query(oppSOQL); newRecord = currentRecord.clone(false); newRecord.ApprovalStatus__c = Status.NotSubmitted; newRecord.Type = 'Existing Client: Campaign Renewal'; newRecord.SalesPlanner__c = null; newRecord.RequestType__c = null; newRecord.DeliverableDueDate__c = null; newRecord.PORequired__c = null; newRecord.PONumber__c = null; newRecord.PrePay__c = null; newRecord.Campaign_Event__c = null; newRecord.ExistingConversionVolume__c = null; newRecord.ClonedFrom__c = currentRecord.id; insert newRecord; //--------Cloning the Opp Team Test-------- List<OpportunityTeamMember> relatedTeamMembers = new List<OpportunityTeamMEmber>(); for(OpportunityTeamMember tm : [SELECT OpportunityAccessLevel, OpportunityId, UserId, TeamMemberRole FROM OpportunityTeamMember WHERE OpportunityId =: CurrentRecord.id]){ OpportunityTeamMember otm = tm.clone(false); otm.OpportunityID = newRecord.Id; relatedTeamMembers.add(otm); } insert relatedTeamMembers; List<OpportunityShare> relatedOppShare = new List<OpportunityShare>(); for(OpportunityShare os : [SELECT OpportunityAccessLevel,OpportunityId,RowCause, UserOrGroupID FROM OpportunityShare WHERE OpportunityID =:CurrentRecord.id AND RowCause = 'Sales Team']){ OpportunityShare nOS = os.clone(false); nOS.OpportunityID = newRecord.id; relatedOppShare.add(nOS); } insert relatedOppShare; } catch(Exception e){ Database.rollback(sp); ApexPages.addMessages(e); return null; } return new PageReference('/'+newRecord.id); } }
- mgodsey
- September 18, 2013
- Like
- 0
- Continue reading or reply
Using DescribeField methods to dynamically retrieve field API names and labels
I have a trigger on Opportunity that updates a text field on the Opportunity called WhatChanged__c. It's comparing the values on two related Opportunities and seeing if they are different. I need to reference the Field Label in the WhatChanged__c value, and I want to make it dynamic so that if we change any field labels/api names in the future the code will automatically handle the change.
Here is the relevant part of trigger:
//continue if there are cloned Opps moving into the pending stage if(!pendingClonedOpps.isEmpty()){
//get all the labels for Opportunity fields and put them in a map, keyed to the field api name String objectType ='Opportunity'; Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe(); Schema.SObjectType leadSchema = schemaMap.get(objectType); Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap(); Map<String, String> fieldAPIName = new Map<String, String>(); for(String fieldName : fieldMap.keySet()){ fieldAPIName.put(fieldName, fieldMap.get(fieldName).getDescribe().getLabel()); } for(Opportunity opp : pendingClonedOpps){ //List to store all of the names of fields that have changed List<String> Changes = new List<String>(); //get the related Cloned Opportunity record Opportunity clonedFromOpp = ClonedOppIDToClonedOpp.get(opp.ClonedFrom__c); if(opp.Buyer__c != clonedFromOpp.Buyer__c){ String fieldName = 'buyer__c'; String Label = fieldAPIName.get(fieldName); String oldBuyer = clonedFromOpp.Buyer__c; Changes.add(Label+': '+oldBuyer); } opp.WhatChanged__c = CSUtils.join(Changes, ' '); }
It's working, but the part I'm not happy with is the line String fieldName = 'buyer__c'. If the API name for that field ever changes, I will need to update the fieldName variable. Is there a way to dynamically get the API name, in a similar way to how I am getting the field name? Can I create a Map that stores <Field, String>? This is my first time working with Describe.field() methods so I think I'm confusing myself!
Any help is much appreciated! Thanks!
- mgodsey
- September 11, 2013
- Like
- 0
- Continue reading or reply
Help with Querying all Fields on an Object
I want to be able to query for all creatable fields on an object without having to hardcode each field into the SOQL query. I have a method that builds the SOQL query and it works great except for when the WHEN statement includes id in: a collection of records.
Here is the method:
/** *Returns a dynamic SOQL statement for the whole object, includes only creatable fields since we will be inserting a cloned result of this query */ public static string getCreatableFieldsSOQL(String objectName, String whereClause){ String selects = ''; if(whereClause == null || whereClause == ''){ return null; } //get a map of field names and field tokens Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(objectName.toLowerCase()).getDescribe().Fields.getMap(); List<String> selectFields = new List<String>(); if(fMap!=null){ for(Schema.SObjectField ft : fMap.values()){ //loop through all field tokens (ft) Schema.DescribeFieldResult fd = ft.getDescribe(); //describe each field (fd) if (fd.isCreateable()){ //field is creatable selectFields.add(fd.getName()); } } }
Here is where I invoke the method:
String oppSOQL = CSUtils.getCreatableFieldsSOQL('Opportunity', 'id in' + clonedFromOppIDs); system.debug('[MF] oppSOQL: ' + oppSOQL); for(Opportunity opp : (List<Opportunity>)Database.query(oppSOQL)){ ClonedOppIDtoClonedOpp.put(opp.id, opp); }
"clonedFromOppIDs" is a set of Opportunity IDs. However, when I try to execute this code I get the error message: System.QueryException: unexpected token: '{' . This is the debug log (I removed most of the fields to make it easier to read):
16:56:07.493 (493363000)|USER_DEBUG|[28]|DEBUG|[MF] oppSOQL: SELECT ApprovedTerms__c,Rate_Type__c,WhatChanged__c FROM Opportunity WHERE id in{006Q000000BmT4XIAV} 16:56:07.493 (493388000)|SYSTEM_METHOD_EXIT|[28]|System.debug(ANY) 16:56:07.493 (493412000)|SYSTEM_METHOD_ENTRY|[30]|Database.query(String) 16:56:07.494 (494079000)|EXCEPTION_THROWN|[30]|System.QueryException: unexpected token: '{'
I've tried making the WHERE clause 'id in: ' + clonedFromOppIDs but I get the same error message. Does anyone know if there is anyway I can get around this? Or have other suggestions for how to systematically query all fields without typing each one it? Any help would be much appreciated, thank you!!
- mgodsey
- September 10, 2013
- Like
- 0
- Continue reading or reply
Unit Test for Extension Class for Custom Cloning
I have a VF page and Controller Extension that allows me to clone a custom object (ProposalFlight__c) record. The ProposalFlight__c record has a lookup field to another custom object, called Geo__c. Using the VF page (which overrides the custom clone button) and the Controller Extension, I am able to clone both ProposalFlight__c and Geo__c at the same time. However, I'm really struggling with creating the unit test for the controller extension.
VF Page:
<apex:page standardController="ProposalFlight__c" extensions="ProposalFlightCloneExtension" action="{!cloneRecord}"> <apex:pageMessages /> </apex:page>
Controller Extension (I've replaced the fields that are actually in the queury with (all Fields) just to make it reasier to read here):
public class ProposalFlightCloneExtension{ //Variable to hold current record ProposalFlight__c currentRecord; //Standard constructor method public ProposalFlightCloneExtension(ApexPages.StandardController controller){ currentRecord = (ProposalFlight__c)controller.getRecord(); } public PageReference cloneRecord(){ //Variable to hold the new record ProposalFlight__c newRecord; Savepoint sp = Database.setSavepoint(); try{ //first clone the Geo Record Geo__c clonedGeo; for(Geo__c relatedGeo: [SELECT (All Fields) FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE id=: currentRecord.id)]){ Geo__c newGeo = relatedGeo.clone(false); clonedGeo = newGeo; } insert clonedGeo; //now clone the Proposal Flight currentRecord = [SELECT (All Fields) FROM ProposalFlight__c WHERE id=:currentRecord.id]; newRecord = currentRecord.clone(false); newRecord.ApprovalStatus__c = Status.NotSubmitted; newRecord.ClonedFrom__c = currentRecord.id; newRecord.Geo__c = clonedGeo.ID; newRecord.GeoTargetSummary__c = clonedGeo.Text__c; insert newRecord; }catch(Exception e){ Database.rollback(sp); ApexPages.addMessages(e); return null; } return new PageReference('/'+newRecord.id); } }
My Unit Test so far:
@isTest (SeeAllData = True) private class Test_ProposalFlightCloneExtension{ static testMethod void testProposalFlightClone(){ //create test data Account acct = UnitTestFactory.makeAccount(); Opportunity opp = UnitTestFactory.makeMasterCPMOpp(acct.id); ProposalFlight__c pf = UnitTestFactory.makeCPMPF(opp.id); Geo__c geo = [SELECT Id FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE Id =: pf.Id)]; //Go to Page Test.setCurrentPage(Page.ProposalFlightClone); //Set Parameters that would be passed in ApexPages.currentPage().getParameters().put('Id', pf.Id); //Instantiate a new controller with all parameters in place ProposalFlightCloneExtension ext = new ProposalFlightCloneExtension(new ApexPages.StandardController(pf)); PageReference pageRef = Page.ProposalFlightClone; } }
The unit test passes, but is only covering 12% of the class. It doesn't cover any of the actual cloning logic. If anyone could point me in the right direction I would really appreciate it. Thank you!
- mgodsey
- September 05, 2013
- Like
- 0
- Continue reading or reply
Possible to write trigger to re-establish product opportunity revenue schedule?
Can anyone point me in the direction of any triggers that are used to automatically re-establish revenue schedules (for example, if the Opp Close Date changes). Is this even possible?
Thank you so much for the help!
- mgodsey
- October 02, 2012
- Like
- 0
- Continue reading or reply
StandardSetController cancel() and save() issue
Hi,
I have a visualforce page where I populate a PageBlockDataTable with a list<sObject> using StandardSetController.getRecords(). There are some fields in the table that are inputFields to allow edits. Pagination is implemented and works fine if nothing is edited.
I read that either cancel() or save() needs to be run before moving to another page otherwise visualforce will throw an error saying 'modified rows exist in the collection'. So when records are edited, I have a javascript that detect changes and prompts user whether to save or cancel before moving to next page, which then through calling actionFunction runs the StandardSetController's cancel() / save() and then next() / previous() / setPageNumber(x) in a method in the page's controller.
Problem: After running that, let's say cancel() and next(), getResultSize() becomes lesser and the collection shrunk. Although getPageNumber() appear to be working, something is wrong as there are lesser pages now in the paginated table. Debug log shows that getResultSize() has indeed become lesser after ApexPages.StandardSetController.cancel() is run.
Any idea what could be wrong? any feedback/solution recommended is much appreciated. Thanks.
- tk.service
- August 28, 2012
- Like
- 0
- Continue reading or reply
In pageBlockButtons, <apex:facet> only works with top set of buttons
I have functionality in a form so when the users click on the button, the button goes disabled. The only problem I have is that in a <apex:pageBlockButtons> block, where two sets of buttons are created, only the top set of buttons becomes disabled. This was put into place to prevent the users from double-clicking the buttons, however they end up double-clicking the lower set of buttons because those buttons do not become disabled.
<apex:pageBlockButtons id="productButtons">
<apex:actionStatus rendered="{!NOT(readOnly)}" id="applyButtonStatus">
<apex:facet name="stop">
<apex:commandButton id="applyButtonActive" action="{!calcRevenue}" value="Apply Changes/Calculate Revenue" status="applyButtonStatus" disabled="false" rerender="productTypeSelectionBlock"/>
</apex:facet>
<apex:facet name="start">
<apex:commandButton id="applyButtonDisabled" action="{!calcRevenue}" value="Applying Changes..." status="applyButtonStatus" disabled="true" rerender="productTypeSelectionBlock"/>
</apex:facet>
</apex:actionStatus>
</apex:pageBlockButtons>
Is there any way to get this to work inside of the pageBlockButtons block, or do I just have to create two sets of buttons? If I create two sets, then they'll disable independently of each other, which isn't ideal.
- dcarmen66
- March 20, 2012
- Like
- 0
- Continue reading or reply