-
ChatterFeed
-
3Best Answers
-
0Likes Received
-
0Likes Given
-
22Questions
-
49Replies
learn apex
Hello,
i have a short question. What is the best way to learn apex?
I know how to programme php, js and stuff like that and to save time i wanted to ask you what you think is the fastest way.
- dyn1
- May 12, 2011
- Like
- 0
Custom Button not passing ID
hi,
I have a custom button that I use to pass two id's to a controller. The button allows me to launch a VF page from a related list. This button was working fine, but has suddenly started throwing an invalid id error. My first assumption was that it had to do with the introduction of a new record type, which was causing an error in my controller somewhere, but I quickly noticed that the button was setting up the URL incorrectly. So, the button is meant to pass two ids one for custom object Goal__c and another for Account, and their query string variables are gid and aid, respectively. I noticed that when I click the button and get the error message that aid does not have the account's id assigned, and the error message points me to first line of code that works with account id. To further confuse things, I have buttons that work in a very similar matter, but they are launched from a different object, but still rely on account id in the same way...these still work fine. So, I'm curious to know if anybody has any ideas on why this might be failing.
Here is url that the button sets up: /apex/narrativeWizard3?gID={!Goal__c.Id}&aID={!Account.Id}
- aKallNV
- October 17, 2011
- Like
- 0
Problems with saving records coming from a wrapper class in a map
I have been struggling with this VF page for a while now. Here is the scenario.
I have a custom object(I will refer to it as 'swpl') that I have set up a many-to-many relationship with on a few other objects...2 custom objects, contacts and cases to be exact. So what my VF page does is allows you to enter data for a new swpl record and then use a Multi-tab vf page to click of the various records that you want to relate the record to. So you can picture 4 tabs one for each of the custom objects and one for contacts and the fourth for cases. For each one of these tabs I have written wrapper classes so that the records can be clicked by the user and then saved as a junction record. So all seems to be ok except for one of my custom objects. I know it has something to do with the fact that I tried to make things more complicated with the particular tab. In this case the custom object is the child of another record. Therefore I tried to set up the list on the vfPage so that each child object is grouped by a it's parent record...rather than repeating the Parent record name for each Child Object.
Somehow the maps that I use to genarate this is causing some strange save behavior that I have not been able to find a pattern for. So i am posting the code hoping that some brilliant person can spot what i am doing wrong. the problem is that not all of the records that are checked are saved, and what is even more strange is that it will save records that were not checked.
I have added some underlined text to the code to help get you in the right spot. I you're interested, and have left out the bits of code that arent' pertinent.
public without sharing class narrativeWizard_Controller { public SchoolWorkPlanLog__c swpn { get; set; } public String accountId; public String theUserUnit;//strings for setting up Dynamic SOQL public String theUserDept;//string for setting up Dynamic SOQL public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public Map<Id,DeployedStrategy__c> theVFDSs { get; set; } public List<Goal__c> theGoals { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public List<cCONS> theConWrappers { get; set; } public Set<String> caseRTOptions = new Set<String>(); //for case record type options public String selectedCaseRT { get; set; } public List<Case> theCases { get; set; } public List<cCASES> theCaseWrappers { get; set; } public User theUser { get; set; } public Set<String> goalUnitOptions = new Set<String>(); public String selectedGoalUnit { get; set; } public boolean showAll { get; set; } //controls wether or not only priority Action Items or all Action items are shown. public datetime fromDate; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.swpn.Account__c = ApexPages.currentPage().getParameters().get('aID'); this.accountId = ApexPages.currentPage().getParameters().get('aID'); this.setUptheUser(); this.selectedUnit = setUptheUser().Unit__c; this.showAll = false; this.fromDate = datetime.newInstance(2011,5,1);//for Case Query Criteria this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getStratyUnits(); //this.makeCaseRTOptions(); this.getAllGoals(); } //pulls the user who initiated the log so that lists can be filtered to the Unit they belong to. I need to make this return a User object so that I can reference more fields. public User setUpTheUser() { ID UP = Userinfo.getUserId(); User userX = [select ID, Name, Email, Department__c, Unit__c from User where ID =:UP]; this.theUserUnit = userX.Unit__c; this.theUserDept = userX.Department__c; return userX; } public void getStratyUnits() { theUser = setUptheUser(); for (DeployedStrategy__c ds : [select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :this.swpn.Account__c And Status__c = 'Active']) { unitOptions.add(ds.Unit__c); } } public String getStrategyQuery() { String losFilters = ''; if(this.selectedUnit != 'All' && (this.selectedUnit != 'Charter' && this.selectedUnit != 'Cross Unit: Coach' && this.selectedUnit != 'Not Applicable')) { losFilters += ' AND Unit__c =:selectedUnit'; } else if(this.selectedUnit == 'Charter' ){ losFilters += ' AND Department__c =:theUserDept'; }else if((this.selectedUnit == 'Not Applicable' && this.theUserDept != 'Not Applicable') || this.selectedUnit == 'Cross Unit: Coach') { losFilters += ' AND Department__c = :theUserDept'; }else if(this.selectedUnit == 'Not Applicable' && this.theUserDept == 'Not Applicable') { losFilters += ''; } else if(this.selectedUnit == 'All') { losFilters += ''; } else { losFilters += ''; } return 'select ID, Name, Status__c, Principle__c, Strategy__r.FullName__c, Strategy__r.Name,Strategy__r.Category__r.Name, Strategy__r.Category__r.Principle__r.Name, EndDate__c, Unit__c, StartDate__c, (select ID, Name, Name__c, Status__c, Stage__c, ActionItemName__r.ActionItemFullName__c, SequenceNumber__c, ItemNumber__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c, LatestRating__c from DeployedActionItem__r where Stage__c != \'Not Needed\' Order By ItemNumber__c ASC) from DeployedStrategy__c where Account__c = :accountId And Status__c != \'Inactive\''+losFilters+' ORDER BY Unit__c, StartDate__c ASC'; } //attempt at Dynamic Query public void makesStrategyWrappers() { theDSs = new List<DeployedStrategy__c>(); theVFDSs = new Map<Id,DeployedStrategy__c>(); List<cAIS> cAIS1 = new List<cAIS>(); theWrappers = new List<cAIS>(); theWrapperMap = new Map<Id, List<cAIS>>(); String queryString = this.getStrategyQuery(); theDSs = Database.query(queryString); if(theDSs.size() > 0) { for(DeployedStrategy__c ds : theDSs) { if(ds.DeployedActionItem__r.size() > 0) { for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { if((actI.Status__c == 'Priority' || actI.Status__c == 'Overdue Priority') && actI.Stage__c != 'Completed' && !this.showAll) { theVFDSs.put(ds.id,ds); This is the map that I use to create the Parent Headings in the VF page cAIS1 = theWrapperMap.get(ds.Id); This is the Map that makes up the child records in the VFpageif(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } if(this.showAll){ theVFDSs.put(ds.id,ds); cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } } } } } } public List<DeployedStrategy__c> getKeys() { return theVFDSs.values(); } //Method called by Save Button public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = this.swpn; insert newLog; //insert new Junction Records List<UniversalJoin__c> newJuncObjs1 = new List<UniversalJoin__c>(); List<DeployedActionItems__c> selectedAIs = new List<DeployedActionItems__c>(); List<Contact> selectedCons = new List<Contact>(); LIst<Case> selectedCases = new List<Case>(); List<Goal__c> selectedGs = new List<Goal__c>(); //List<ActionItemRating__c> newRatings = new List<ActionItemRating__c>(); for(DeployedStrategy__c ds : this.theVFDSs.values()) { for(cAIS ai : this.theWrapperMap.get(ds.ID)) { //system.assert(false,'Your Results '+this.theWrapperMap.get(ds.ID)); if(ai.selected == true) {This is where the problmes start. It's putting the wrong values in the selectedAIs list. selectedAIs.add(ai.wAI); } } } if(selectedAIs.size() > 0) { for(DeployedActionItems__c ds2 : selectedAIs) { UniversalJoin__c newJuncOb = new UniversalJoin__c( SchoolWorkPlanLog__c = newLog.Id, ActionItem__c = ds2.Id, RecordTypeId = '012Q0000000CwfBIAS'); newJuncObjs1.add(newJuncOb); }
<apex:page sidebar="false" showHeader="true" standardController="SchoolWorkPlanLog__c" extensions="narrativeWizard_Controller" id="tt1"> <apex:form > <apex:pageBlock id="pb1" mode="edit"> <apex:pageBlockSection title="{!swpn.Account__r.Name}" columns="1"> <apex:inputField value="{!swpn.Subject__c}"/> <apex:inputField value="{!swpn.InteractionDate__c}"/> <apex:inputField value="{!swpn.HoursSpent__c}" /> <apex:inputField value="{!swpn.CategoryofWork__c}" /> <!--<apex:inputField value="{!getLog.PreEngagementPlan__c}"/>--> <apex:inputField value="{!swpn.Narrative__c}" style="width:90%"/> </apex:pageBlockSection> <!--<apex:pageBlockSection columns="1" collapsible="true" title="Next Steps"> <b><apex:outputLabel value="Use the following fields to define your next step. Upon saving this record a new Log will be created with the Date and Plan that you specify here."/></b> <apex:inputField value="{!getLog.NextStepDate__c}"/> <apex:inputField value="{!getLog.NextStepPlan__c}"/> </apex:pageBlockSection>--> <!--<apex:pageBlockSection columns="1" id="pbs1" title="Off-Plan?"> <apex:outputPanel > <b><apex:outputLabel value="Check the box to indicate that none of the options below are appropriate:"/></b> <apex:actionRegion > <apex:inputField value="{!getLog.OffPlan__c}"> <apex:actionSupport event="onclick" reRender="catField, pb2"/> </apex:inputField> </apex:actionRegion> </apex:outputPanel> </apex:pageBlockSection> <apex:outputPanel id="catField"> <apex:pageBlockSection rendered="{!showAIandGoal = false}" columns="1"> <b><apex:outputText value="Find a category that best classifies this narrative:"/></b> <apex:inputField value="{!swpn.Category__c}"/> </apex:pageBlockSection> </apex:outputPanel> --> </apex:pageBlock> <apex:pageBlock id="pb2"> <apex:pageBlockButtons > <apex:commandButton action="{!processSelected}" value="Save" /> <apex:commandButton action="{!cancelButton}" value="Cancel" /> </apex:pageBlockButtons> <apex:pageBlockSection title="Select the Work Plans, Goals, Cases and Contacts that this Entry pertains to." collapsible="false" columns="1"> <apex:tabPanel switchType="client" selectedTab="tab1" > <apex:tab label="Work Plans" id="tab1"> <apex:pageBlockSection columns="1" id="pbs1" title="Off-Plan?"> <apex:outputPanel > <b><apex:outputLabel value="Check the box to indicate that none of the options below are appropriate:"/></b> <apex:actionRegion > <apex:inputField value="{!swpn.OffPlan__c}"> <apex:actionSupport event="onclick" reRender="catField, workplans"/> </apex:inputField> </apex:actionRegion> </apex:outputPanel> </apex:pageBlockSection> <apex:outputPanel id="catField"> <apex:pageBlockSection rendered="{!showAIandGoal = false}" columns="1"> <b><apex:outputText value="Find a category that best classifies this narrative:"/></b> <apex:inputField value="{!swpn.Category__c}"/> </apex:pageBlockSection> </apex:outputPanel> <apex:outputPanel id="workplans"> <apex:pageBlockSection collapsible="false" columns="3" rendered="{!showAIandGoal}" id="filters" title=""> <apex:pageBlockSectionItem > <apex:outputLabel value="Check to Show All. Uncheck to Show Only Priorities"/> <apex:actionRegion > <apex:inputCheckbox value="{!showAll}"/> <apex:actionSupport event="onclick" action="{!makesStrategyWrappers}" reRender="table1"/> </apex:actionRegion> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel value="Filter by Unit"/> <apex:selectList value="{!selectedUnit}" size="1" id="uniList"> <apex:selectOptions value="{!Units}"/> <apex:actionSupport event="onchange" reRender="princyList" status="UnitStatus" /> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:commandButton action="{!makesStrategyWrappers}" reRender="table1" value="Filter"> <apex:actionSupport event="onchange" status="buttonStatus"/> <apex:actionStatus id="buttonStatus" startText="Diving for Records..."/> </apex:commandButton> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection collapsible="false" columns="1" id="table1" rendered="{!showAIandGoal}"> <apex:pageBlockSectionItem > <apex:outputPanel layout="block" style="overflow:auto;width:1180px;height:400px" > <apex:pageBlockTable value="{!Keys}" var="d" cellspacing="15px"> calls getKeys Method <apex:column headerValue="Strategy"> <b>{!d.Strategy__r.FullName__c }</b> </apex:column> <apex:column headerValue="Unit"> <b>{!d.Unit__c}</b> </apex:column> <apex:column headerValue="Principle"> <b>{!d.Principle__c}</b> </apex:column> <apex:column headerValue="Status"> <b>{!d.Status__c}</b> </apex:column> <apex:column headerValue="Start Date" width="125"> <b><apex:outputText value="{0,date,MM-dd-yyyy}"> <apex:param value="{!d.StartDate__c}"/> </apex:outputText></b> </apex:column> <apex:column breakBefore="true" colspan="5" > child records <apex:dataTable value="{!theWrapperMap[d.id]}" var="a" width="100%" border="5px" cellspacing="10px"> <apex:column > <apex:inputCheckbox value="{!a.selected}"/> </apex:column> <apex:column headerValue="Action Items"> {!a.wAI.ActionItemName__r.ActionItemFullName__c} </apex:column> <apex:column headerValue="Item Number"> {!a.wAI.ItemNumber__c} </apex:column> <apex:column headerValue="Status"> {!a.wAI.Status__c} </apex:column> <!--<apex:column headerValue="Current Rating" width="110"> {!a.wAI.LatestRating__c} </apex:column> </apex:pageBlockTable> </apex:outputPanel> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:outputPanel> </apex:tab>....
- aKallNV
- October 01, 2011
- Like
- 0
Formula field not evaluating in test class
I have a formula field called 'Status' that assigns a Status to a record based on the value provided in a date field on the same record. Simply put the logic is: If Start Date is not null then Status equals 'Priority'. Otherwise Status equals 'Inactive'.
I have tested this pretty thouroughly in the UI and haven't found any problems.
I am using this object in a VF controller and I need to test both conditions...the records that are a Priority and the records that are Inactive. So my test inserts a bunch of records without a Start Date which means that none of them would be a Priority. I then try to update some of those records with a Start Date to test the other condition. Here is where I am running into trouble. For some reason, the formula is not evaluated. I have verified with system.debug that although there is a Start Date present on the records the Status field is still 'Inactive'.
Does anybody know why the formula field would not fire in a test method?
- aKallNV
- August 13, 2011
- Like
- 0
VF controller: Why aren't two of several fields being saved?
The code posted below is a small portion of a VF controller. This portion is part of a Save Method that inserts a new record in a custom object. I have had this working fine for a few weeks now. However, I was just provided a new business need, which is simply the addition of two new fields. For some reason the data in these fields are not being inserted. All of the other fields are being saved just fine. The two new fields are callled CategoryofWork__c and HoursSpent__c. They are simply a picklist field and an integer field. I can't spot any difference between them and the other fields that would prevent them from being inserted. No errors are thrown. The record simply saves without the data.
Any ideas?
Thanks!
//Method called by Save Button public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = accountID, Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c, CategoryofWork__c = this.getLog.CategoryofWork__c, HoursSpent__c = this.getLog.HoursSpent__c, Category__c = this.getLog.Category__c, OffPlan__c = this.getLog.OffPlan__c, Department__c = this.getLog.Department__c, Unit__c = this.getLog.Unit__c ); insert newLog;
- aKallNV
- August 11, 2011
- Like
- 0
Table rows repeating for each Child Record present in Parent to Child Query
Hi all,
This method populates a pageblockTble that I have built which groups child records by their parent records. I have a simpler version of this method that works fine. However, just got the need for some new logic, and now I'm struggling. The request requires me to provide two different iists based on criteria in the Child records. The problem is that I'm getting repeating values for each child object. For example, if there are 3 child objects then I see the group of 3 child Objects and its parent repeated 3 times in the table. I understand why this is happening. I have comments to code below to explain.
thanks!
public void makesStrategyWrappers() { theDSs = new List<DeployedStrategy__c>(); theVFDSs = new List<DeployedStrategy__c>();//I use this variable in my VF page as a map key for grouping the child objects List<cAIS> cAIS1 = new List<cAIS>(); theWrappers = new List<cAIS>(); theWrapperMap = new Map<Id, List<cAIS>>(); String queryString = this.getStrategyQuery(); theDSs = Database.query(queryString); if(theDSs.size() > 0) { for(DeployedStrategy__c ds : theDSs) { if(ds.DeployedActionItem__r.size() > 0) { for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { if(actI.Status__c == 'Priority' && actI.Stage__c != 'Completed' && !this.showAll) { theVFDSs.add(ds); //here is where I populate the key. The values repeat because for each child that Iterate //through it adds the same key parent value. How do I populate this with just unique ideas. I tried a set but that just seems to throw errors. cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } if(this.showAll){ theVFDSs.add(ds); cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } } } } } }
- aKallNV
- August 05, 2011
- Like
- 0
Need help with debugging 'An Internal Sever Error has occured'
Hi all,
The code below is a class with two methods. Both methods are called by an After Insert trigger on my custom obj called DeployedStrategy__c.
The createActionItems method is the one that I wrote first, and it does exactly what I want it to do. To briefly summarize what that is...I have four custom objs. Two of them define a template for Strategies and Action Items that belong to those strategies. The other two represent instances of those strategies...the main difference being that they are tied to an an Account record. So this method inserts all of the Action Items that belong to the Strategy as defined in the template.
The checkForDupeStratys method is my attempt to handle a different business need, which is to prevent a Business Unit from creating more than one of the same Strategy. Business Units are assigned to instances of Strategies (DeployedStrategy__c) via a workflow rule, which simply updates the Unit__c field with the Unit defined on the creating user's record. Therefore this method is attempting to pull all existing strategies that belong to the same Account as the newly inserted strategy and comapre if they use the same Strategy Template(Strategy__c field) and belong to the same Unit(Unit__c field).
I get the following: "An internal server error has occured" and then it goes on to say that SFDC support has been notified, please provide any additional info I think would help, we applogize for the inconvenience, and an error ID.
I have never encountered one of these before and I'm not sure what's causing it. And I think it has to do the checkForDupeStratys method beause the other one is working fine when I use it on its own.
The thing that stumps me is that I have put system.assert(false,) throughout both methods to test for which lines of code are being hit....and on every line the system.assert message was thrown instead of the 'An Internal server error' message.
public with sharing class nvpsDeployedStrategyHandler { public static void checkForDupeStratys(List<DeployedStrategy__c> newStrats) { Set<id> acctIDs = new Set<id>(); Map<ID, List<DeployedStrategy__c>> exStratys = new Map<ID, List<DeployedStrategy__c>>();//the IDs are Account IDs...a Map of Account IDs to the Strategies that belong to the Account //populates variables needed for remaining code. for(DeployedStrategy__c newStrat: newStrats) { acctIDs.add(newStrat.Account__c); } //The next two for loops were written to prevent the insertion of duplicate Strategies. for(DeployedStrategy__c exStrat : [select ID, Name, Account__c, Unit__c, Strategy__c from DeployedStrategy__c where Account__c IN :acctIDs AND Status__c = 'Active']) { List<DeployedStrategy__c> exSs = exStratys.get(exStrat.Account__c); if(null == exSs) { exSs = new List<DeployedStrategy__c>(); exStratys.put(exStrat.Account__c, exSs); } exSs.add(exStrat); } for(DeployedStrategy__c ds : newStrats) { for(DeployedStrategy__c eDS : exStratys.get(ds.Account__c)) { if((ds.Unit__c == eDS.Unit__c) && (ds.Strategy__c == eDS.Strategy__c)) { ds.addError(eds.Unit__c+' has already deployed this Strategy. Please refer to '+ds.Name); }else { createActionItems(newStrats); } } } } public static void createActionItems(List<DeployedStrategy__c> newStrats) { Set<id> stratyTempIDs = new Set<id>(); //Set of Ids for all the Strategy Templates that the Inserted Strategies are related to. Map<Id,List<StrategyActionItem__c>> aiTemplates = new Map<Id,List<StrategyActionItem__c>>(); //Map of Action Item templates that belong to the same Strategy Template as the Inserted Strategies. Mapped to the Strategy Template Id. List<DeployedActionItems__c> newAIs = new List<DeployedActionItems__c>(); //A list of the new Action Items to be Inserted and related to the Inserted Strategies that came from the Trigger. //populates variables needed for remaining code. for(DeployedStrategy__c newStrat: newStrats) { stratyTempIDs.add(newStrat.Strategy__c); } //The remaining code generates the Action Items that belong to each strategy. for(StrategyActionItem__c aiTemplate : [select ID, Name, Strategy__c, ItemNumber__c, ActionItem__r.Name from StrategyActionItem__c where Strategy__c IN :stratyTempIDs]) { // look for existing entry in map List<StrategyActionItem__c> aitemps = aiTemplates.get(aiTemplate.Strategy__c); if(null == aitemps) { aitemps = new List<StrategyActionItem__c>(); aiTemplates.put(aiTemplate.Strategy__c, aitemps); } aitemps.add(aiTemplate); } for(DeployedStrategy__c strat : newStrats) { for(StrategyActionItem__c aitemp : aiTemplates.get(strat.Strategy__c)) { DeployedActionItems__c newDAI = new DeployedActionItems__c( ActionItemName__c = aiTemp.Id, Name__c = aiTemp.ActionItem__r.Name, ItemNumber__c = aiTemp.ItemNumber__c, Stage__c = 'Not Started', KBaseMember__c = True, DeployedStrategy__c = strat.Id ); newAIs.add(newDAI); } } insert newAIs; } }
- aKallNV
- July 19, 2011
- Like
- 0
Struggling with ajax
In fact, struggling with a lot...this is like the eleventeenth post I've made on this page and controller...it just keeps getting bigger. Anyway, here is the situation. I have a datatable that I want to allow users to filter with two different picklists, which are called Unit and Principle. The datatables are reRendered based on dynamic soql queries generated by what they select from the filter picklists, and the constructor is set up so that the page defaults to be filtered to only record's in the User's Unit and All Principles. The user has to select the combination of Unit and Principle that they want and then click a Filter button to get a different view. I actually have all that working.
The part that I am struggling with is getting the two picklist values to reRender. The Unit that a User selects should change the available Principles to select from and vice versa. So I am trying to use dynamic soql for this too. There were points in my playing around with it that it kind of worked...it would work up until the first time I clicked the filter button, but then anytime after it just pulled all values, and now it's just pulling all Values, and I can't get back to the partial success I was having. I'm pretty lost and tired at this point, so I am just going to throw the code out there to see if any of you has any ideas or opinions. Thanks!
BTW, I am not going to post the entire controller or page because they are getting pretty long.
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public List<Goal__c> theGoals { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public Set<String> princyOptions = new Set<String>(); public String selectedPrincy { get; set; } //public Set<String> catyOptions = new Set<String>(); //public String selectedCaty { get; set; } public List<cCONS> theConWrappers { get; set; } public List<cCASES> theCaseWrappers { get; set; } public String unitFilter { get; set; } public Set<String> goalUnitOptions = new Set<String>(); public String selectedGoalUnit { get; set; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getLog= new SchoolWorkPlanLog__c(); this.setUpUnitFilter(); this.selectedUnit = setUpUnitFilter(); this.selectedGoalUnit = setUpUnitFilter(); this.getAllStrategyUnits(); this.getStratyPrincys(); this.getAllGoals(); } //pulls the Account from which the Log was initiated. public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; } //pulls the user who initiated the log so that lists can be filtered to the Unit they belong to. public String setUpUnitFilter() { ID UP = Userinfo.getUserId(); User userX = [select ID, Name, Department__c, Unit__c from User where ID =:UP]; return userX.Unit__c; } //pulls all Strategies to generate inital list of Unit options. public void getAllStrategyUnits() { for(DeployedStrategy__c aDS : [select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = 'Active']) { unitOptions.add(aDS.Unit__c); } } //generates query strings to pull Unit Options based on the Princple that was chosen. public void getStratyUnits() { List<DeployedStrategy__c> theDSs2= new List<DeployedStrategy__c>(); String queryString2; if(this.selectedPrincy != 'All') { queryString2 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\' and Principle__c =:selectedPrincy'; } if(this.selectedPrincy == 'All') { queryString2 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''; } theDSs2 = Database.query(queryString2); for(DeployedStrategy__c aDS : theDSs2) { unitOptions.add(aDS.Unit__c); } } public void getStratyPrincys() { List<DeployedStrategy__c> theDSs3= new List<DeployedStrategy__c>(); String queryString3; if(this.selectedUnit != 'All') { queryString3 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\' AND Unit__c =:selectedUnit'; } if(this.selectedUnit == 'All') { queryString3 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''; } theDSs3 = Database.query(queryString3); for(DeployedStrategy__c aDS : theDSs3) { princyOptions.add(aDS.Principle__c); } }
<apex:pageBlock id="pb2"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:commandButton action="{!processSelected}" value="Save" style="left:300px;position:relative;" /> <apex:commandButton action="{!cancelButton}" value="Cancel" style="left:310px;position:relative;"/> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Select the Work Plans, Goals, Cases and Contacts that this Entry pertains to." collapsible="false" rendered="{!showAIandGoal}" columns="1"> <apex:tabPanel switchType="client" selectedTab="tab1" > <apex:tab label="Work Plans" id="tab1"> <apex:pageBlockSection collapsible="false" columns="3"> <apex:pageBlockSectionItem > <apex:outputLabel value="Filter by Unit"/> <apex:selectList value="{!selectedUnit}" size="1" id="uniList"> <apex:selectOptions value="{!Units}"/> <apex:actionSupport event="onchange" reRender="princyList" action="{!getStratyPrincys}" status="UnitStatus" /> <apex:actionStatus id="UnitStatus" startText="Fetching Principles..."/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel value="Filter by Principle"/> <apex:selectList value="{!selectedPrincy}" size="1" id="princyList"> <apex:selectOptions value="{!Princys}"/> <apex:actionSupport event="onchange" reRender="uniList" action="{!getStratyUnits}" status="PrincyStatus"/> <apex:actionStatus id="PrincyStatus" startText="Fetching Principles..."/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:commandButton action="{!makesStrategyWrappers}" reRender="table1" value="Filter"> <apex:actionSupport event="onchange" status="UnitStatus"/> <apex:actionStatus id="UnitStatus" startText="Fetching Records..."/> </apex:commandButton> </apex:pageBlockSectionItem>
- aKallNV
- July 13, 2011
- Like
- 0
What does it take to Override the Edit button?
I have a cutom object that has many-to-many relationships with several other objects via a universal join object. The object kind of works like the Task object...it's purpose is to allow our users to summarize their work for the day and then relate it all things that pertain to it, which could be one or many Contacts, Cases and Two Custom Objects. The object also has a look Up relation to the Account Object. The VF page launches and works pretty well when they click a Custom button, which is just a Create New button on the related list on the Account Detail page. The button passes the account id that the button was clicked from. I use the account id to query for all the various potential related records...for example all open cases that belong to that Account. I also use the passed id to create the relationship to the account in the Save Method.
Again, I have most of that working well, and now I am wondering what I need to do get the same functionality happening from the Edit button. I am pretty novice, so I have little idea on where to start. I notice that the edit button automatically provides the record's id in the url, and that in overriding the edit button you are not allowed to pass any extra ids. So do I have to write a whole bunch more code to work with that id?
The class is already pretty long. So I am just going to post the first few lins so that you can see how I have set up my variables and constructor, and just below the constructor is the method that uses the account id.
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public List<Goal__c> theGoals { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public Set<String> princyOptions = new Set<String>(); public String selectedPrincy { get; set; } //public Set<String> catyOptions = new Set<String>(); //public String selectedCaty { get; set; } public List<cCONS> theConWrappers { get; set; } public List<cCASES> theCaseWrappers { get; set; } public String unitFilter { get; set; } public Set<String> goalUnitOptions = new Set<String>(); public String selectedGoalUnit { get; set; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getLog= new SchoolWorkPlanLog__c(); this.setUpUnitFilter(); this.selectedUnit = setUpUnitFilter(); this.selectedGoalUnit = setUpUnitFilter(); this.getAllStrategyUnits(); this.getStratyPrincys(); this.getAllGoals(); } //pulls the Account from which the Log was initiated. public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; }
- aKallNV
- July 13, 2011
- Like
- 0
using variables in Dynamic SOQL part II
Yesterday, I posted the following code because I couldn't get the unitFilter variable to return a value inside of the getStrategyQuery() method. I managed to get the unitFilter variable working. Now I am stuck on the on selectedUnit variable. It's giving me the same problem...for some reason it's returning null inside of the method. I don't understand why and at a loss at how to get it.
On vf page there is a picklist of selectOptions which are the units. When a user selects a particular unit the page should re-render. I can see in the viewState log that the selectedUnit variable is being populated with the selection made...so again, not sure why it's not being found in the method that uses it to create the query string getStrategyQuery()
thanks for any help.
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public Set<String> princyOptions = new Set<String>(); public String selectedPrincy { get; set; } public Set<String> catyOptions = new Set<String>(); public String selectedCaty { get; set; } public List<cCONS> theConWrappers { get; set; } public List<cCASES> theCaseWrappers { get; set; } public String unitFilter { get; set; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getLog= new SchoolWorkPlanLog__c(); this.getUnits(); this.setUpUnitFilter(); this.getAllStrategies(); } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; } public String setUpUnitFilter() { ID UP = Userinfo.getUserId(); User userX = [select ID, Name, Department__c, Unit__c from User where ID =:UP]; return userX.Unit__c; } //sets up the query string for the makesStrategyWrappers method below private String getStrategyQuery() { unitFilter = setUpUnitFilter(); String losFilters = ''; if(selectedUnit == 'All') { losFilters += ''; }else if((null != selectedUnit) && (selectedUnit != 'All')) { losFilters += ' AND Unit__c =:selectedUnit'; }else if (null != unitFilter) { losFilters += ' AND Unit__c =:unitFilter'; }else { losFilters += ''; } return 'select ID, Name, Status__c, Strategy__r.Name,Strategy__r.Category__r.Name, Strategy__r.Category__r.Principle__r.Name, EndDate__c, Unit__c, StartDate__c, (select ID, Name, Name__c, Status__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c, LatestRating__c from DeployedActionItem__r Order By ItemNumber__c ASC) from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''+losFilters; } //attempt at Dynamic Query public void makesStrategyWrappers() { //variables theDSs = new List<DeployedStrategy__c>(); List<cAIS> cAIS1 = new List<cAIS>(); theWrappers = new List<cAIS>(); theWrapperMap = new Map<Id, List<cAIS>>(); String queryString = this.getStrategyQuery(); theDSs = Database.query(queryString); for(DeployedStrategy__c ds : theDSs) { for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } } } //pulls all Strategies to populate filter options public void getAllStrategies() { for(DeployedStrategy__c ds : [select ID, Name, Status__c, Strategy__r.Name,Strategy__r.Category__r.Name, Strategy__r.Category__r.Principle__r.Name, EndDate__c, Unit__c, StartDate__c, (select ID, Name, Name__c, Status__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c, LatestRating__c from DeployedActionItem__r Order By ItemNumber__c ASC) from DeployedStrategy__c where Account__c = :accountID And Status__c = 'Active']) { unitOptions.add(ds.Unit__c); princyOptions.add(ds.Strategy__r.Category__r.Principle__r.Name); catyOptions.add(ds.Strategy__r.Category__r.Name); } } //makes Goal Wrappers public void makesGoalWrappers() { thegoalWrappers = new List<cGS>(); if(theGoalWrappers.size() <1) { for(Goal__c gs1 : [select ID, Unit__c, Account__c, Name, Status__c, StartDate__c, EndDate__c, Pillar__c, DemographicType__c from Goal__c where Account__c = :accountID and Status__c = 'Active']) { theGoalWrappers.add(new cGS(gs1)); } } }....more code but not relevant.
- aKallNV
- July 06, 2011
- Like
- 0
First time with Dynamic SOQL...can't find variable.
The code below is a VF controller extension of a custom object.
I am trying to create a dynamic SOQL query to allow the user to filter a list.
There is a field on the User object called Unit__c. There is a Unit__c field on the custom object, as well. Both fields contain the same values.
So, what I want is for the user to see a list of the custom objects that belong to his/her unit when they first open the page and have the ability to filter the list by other Unit values that are present. I am having trouble just geting this first part to work. I have created a variable called unitFilter which I populate with a method called setUpUnitFilter which is called in the Contructor. I have debugged the method to verify that is working and does find a value in the Unit__c field, but for some reason when I try to use that value in the method that makes the SOQL query which is called getStrategyQuery() it comes up null everytime...I have tried to populate the variable a few different ways but it always comes up null. I don' think this actually has do with Dynamic SOQL, and more to do with the fact that I am an admin that doesn't fully understand variable instantiation and what not. I have underlined the relevant bits of code and tried add some comments next to them.
Thanks for any help!
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public Set<String> princyOptions = new Set<String>(); public String selectedPrincy { get; set; } public Set<String> catyOptions = new Set<String>(); public String selectedCaty { get; set; } public List<cCONS> theConWrappers { get; set; } public List<cCASES> theCaseWrappers { get; set; } public Boolean firstTime { get; set; } public String unitFilter { get; set; } //here is the filter variable //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getLog= new SchoolWorkPlanLog__c(); this.getUnits(); this.firstTime = true; this.setUpUnitFilter(); //here is where call the method to create the filter } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; } public void setUpUnitFilter() { //here is the method that is called by constructor. verified it finds a Unit ID UP = Userinfo.getUserId(); User userX = [select ID, Name, Department__c, Unit__c from User where ID =:UP]; this.unitFilter = userX.Unit__c; } private String getStrategyQuery() { String losFilters = ''; if(null!=this.selectedUnit) { losFilters += ' AND Unit__c =:selectedUnit'; }else if (null != this.unitFilter) { losFilters += ' AND Unit__c =:unitFilter';//here is where try to use the value created constructor that comes up null. }else { losFilters += ''; } return 'select ID, Name, Status__c, Strategy__r.Name,Strategy__r.Category__r.Name, Strategy__r.Category__r.Principle__r.Name, EndDate__c, Unit__c, StartDate__c, (select ID, Name, Name__c, Status__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c, LatestRating__c from DeployedActionItem__r Order By ItemNumber__c ASC) from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''+losFilters; } //attempt at Dynamic Query public void makesStrategyWrappers() { //variables theDSs = new List<DeployedStrategy__c>(); List<cAIS> cAIS1 = new List<cAIS>(); theWrappers = new List<cAIS>(); theWrapperMap = new Map<Id, List<cAIS>>(); String queryString = this.getStrategyQuery(); theDSs = Database.query(queryString); for(DeployedStrategy__c ds : theDSs) { unitOptions.add(ds.Unit__c); princyOptions.add(ds.Strategy__r.Category__r.Principle__r.Name); catyOptions.add(ds.Strategy__r.Category__r.Name); for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } }.....lots more code below this but probably not relevant
- aKallNV
- July 05, 2011
- Like
- 0
Null Pointer Exception on wrapper class in SOQL sub-Query
My goal is to create a Visual Force table that can group child records by their parent records, and include a checkbox next to the child records to enable further logic when a button is clicked. So, I have figured out how to do wrapper classes to get the checkboxes working (without actually understanding them), and I have also done nested tables in a different VF project. Combining the two has proven to be a real challenge for me, but I think I am really close now...I'm just getting stuck on a null pointer exception. I have included some comments in the code to hopefully help anybody who is interested in helping.
Thanks!
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<ActionItemLogx__c> juncObs { get; set; } //public List<cAIS> actionItems { get; set; } public List<cDS> theWrappers { get; set; } //populates the two wrapper classes defined below public List<cDS> getTheWrappers() { if(theWrappers == null) { List<cAIS> actionItems = new List<cAIS>(); for(DeployedStrategy__c ds : [select ID, Name, Status__c, Strategy__r.Name, (select ID, Name, Name__c, Status__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c from DeployedActionItem__r) from DeployedStrategy__c where DeployedStrategy__c.Account__c = :accountID And Status__c = 'Active']) { for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { actionItems.add(new cAIS(actI)); } //This is where the null pointer exception is thrown. I system.debugged both ds and actionItems to check for values and found values in both. So not sure what the next debug step is. theWrappers.add(new cDS(ds, actionItems)); } } return theWrappers; } public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = ApexPages.currentPage().getParameters().get('aID'), Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c); insert newLog; //insert new Junction Records List<DeployedActionItems__c> selectedAIs = new List<DeployedActionItems__c>(); List<ActionItemLogx__c> newJuncObjs = new List<ActionItemLogx__c>(); for(cDS cd : getTheWrappers()) { for(cAIS ca : cd.ais) { if(ca.selected == true) { selectedAIs.add(ca.wAI); } } } for(DeployedActionItems__c ds2 : selectedAIs) { ActionItemLogx__c newJuncOb = new ActionItemLogx__c( SchoolWorkPlanLog__c = newLog.Id, ActionItem__c = ds2.Id); newJuncObjs.add(newJuncOb); } insert newJuncObjs; PageReference acctPage = new PageReference('/'+accountID); return acctPage; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.getTheWrappers(); this.getLog= new SchoolWorkPlanLog__c(); } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; } //wrapper class for Deployed Strategies public class cDS { public DeployedStrategy__c wDS { get; set; } public List<cAIS> ais = new List<cAIS>(); //wrapper constructor public cDS(DeployedStrategy__c D, List<cAIS> aas) { wDS = D; ais = aas; } } //wrapper class for Action Items public class cAIS { public DeployedActionItems__c wAI { get; set; } public Boolean selected { get; set; } //wrapper class constructor public cAIS(DeployedActionItems__c c) { wAI = c; selected = false; } } }
- aKallNV
- June 05, 2011
- Like
- 0
Wrapper Class in Sub-Query?
I have created a VF page that allows a user to associate a record(SchoolWorkPlanLog__c) with mulitple records via checkboxes by using a wrapper class. It's my first time using a wrapper class, and don't fully understand it...I found a great blog post about them with some sample code. I have everything working great, but there is one thing I can't figure out that would make the page way more functional. The records that the SchoolWorkPlanLog__c record could potentially be tied to have a parent record of their own. So, rather than just show the names of the records that the SchoolWorkPlanLog__c record could be tied to, I would like to group them by the names of their parent records in the table. So my thought was to query the parent record and pull in the child records with a sub-query, but this is complicating things with my wrapper class. So I have posted two versions of the code. The first version is the one that works, and the second is the one that I'm getting lost with.
Works:
public with sharing class narrativeWizard_Controller { public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<ActionItemLogx__c> juncObs { get; set; } public List<cAIS> actionItems { get; set; } public List<cAIS> getAIs() { if(actionItems == null) { actionItems = new List<cAIS>(); for(DeployedActionItems__c ds : [select ID, Name, Status__c, DeployedStrategy__r.Strategy__r.Name, EndDate__c from DeployedActionItems__c where DeployedStrategy__r.Account__c = :ApexPages.currentPage().getParameters().get('aID') And Status__c = 'Active']) { actionItems.add(new cAIS(ds)); } } return actionItems; } public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = ApexPages.currentPage().getParameters().get('aID'), Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c); insert newLog; //insert new Junction Records List<DeployedActionItems__c> selectedAIs = new List<DeployedActionItems__c>(); List<ActionItemLogx__c> newJuncObjs = new List<ActionItemLogx__c>(); for(cAIS cAI : getAIs()) { if(cAI.selected == true) { selectedAIs.add(cAI.wAI); } } for(DeployedActionItems__c ds2 : selectedAIs) { ActionItemLogx__c newJuncOb = new ActionItemLogx__c( SchoolWorkPlanLog__c = newLog.Id, ActionItem__c = ds2.Id); newJuncObjs.add(newJuncOb); } insert newJuncObjs; PageReference acctPage = new PageReference('/'+ApexPages.currentPage().getParameters().get('aID')); return acctPage; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.getAIs(); this.getLog= new SchoolWorkPlanLog__c(); } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :ApexPages.currentPage().getParameters().get('aID') Limit 1]; this.swpnAccount = acct.Name; } //wrapper class public class cAIS { public DeployedActionItems__c wAI { get; set; } public Boolean selected { get; set; } //wrapper class constructor public cAIS(DeployedActionItems__c c) { wAI = c; selected = false; } } }
<apex:page sidebar="false" showHeader="true" standardController="SchoolWorkPlanLog__c" extensions="narrativeWizard_Controller"> <apex:form > <apex:pageBlock mode="edit" > <apex:pageBlockButtons > <apex:commandButton action="{!processSelected}" value="Save"/> </apex:pageBlockButtons> <apex:pageBlockSection title="{!swpnAccount}" > <apex:inputField value="{!getLog.Subject__c}"/> <apex:inputField value="{!getLog.InteractionDate__c}"/> <apex:pageblockSectionItem > <apex:inputField value="{!getLog.Narrative__c}"/> </apex:pageblockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection > <apex:PageBlockTable value="{!actionItems}" var="c"> <apex:column > <apex:inputCheckbox value="{!c.selected}"/> </apex:column> <apex:column headerValue="Name"> {!c.wAI.Name__c} </apex:column> <apex:column headerValue="Status"> {!c.wAI.Status__c} </apex:column> <apex:column headerValue="End Date" width="125"> <apex:outputText value="{0,date,MM-dd-yyyy}"> <apex:param value="{!c.wAI.EndDate__c}"/> </apex:outputText> </apex:column> </apex:PageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
Doesn't work:
public with sharing class narrativeWizard_Controller { public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<ActionItemLogx__c> juncObs { get; set; } public List<cAIS> actionItems { get; set; } public List<cAIS> getAIs() { if(actionItems == null) { actionItems = new List<cAIS>(); for(DeployedStrategy__c ds : [select ID, Account__r.Name, Name, Status__c, EndDate__c, (select ID, Name, Status__c, EndDate__c from DeployedActionItem__r) from DeployedStrategy__c where Account__c = :ApexPages.currentPage().getParameters().get('aID') And Status__c = 'Active']) { for(DeployedActionItems__c dAI : ds.DeployedActionItem__r) { actionItems.add(new cAIS(dAI)); } } } return actionItems; } public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = ApexPages.currentPage().getParameters().get('aID'), Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c); insert newLog; //insert new Junction Records List<DeployedActionItems__c> selectedAIs = new List<DeployedActionItems__c>(); List<ActionItemLogx__c> newJuncObjs = new List<ActionItemLogx__c>(); for(cAIS cAI : getAIs()) { if(cAI.selected == true) { selectedAIs.add(cAI.wAI); } } for(DeployedActionItems__c ds2 : selectedAIs) { ActionItemLogx__c newJuncOb = new ActionItemLogx__c( SchoolWorkPlanLog__c = newLog.Id, ActionItem__c = ds2.Id); newJuncObjs.add(newJuncOb); } insert newJuncObjs; PageReference acctPage = new PageReference('/'+ApexPages.currentPage().getParameters().get('aID')); return acctPage; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.getAIs(); this.getLog= new SchoolWorkPlanLog__c(); } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :ApexPages.currentPage().getParameters().get('aID') Limit 1]; this.swpnAccount = acct.Name; } //wrapper class public class cAIS { public DeployedActionItems__c wAI { get; set; } public Boolean selected { get; set; } //wrapper class constructor public cAIS(DeployedActionItems__c c) { wAI = c; selected = false; } } }
<apex:page sidebar="false" showHeader="true" standardController="SchoolWorkPlanLog__c" extensions="narrativeWizard_Controller"> <apex:form > <apex:pageBlock mode="edit" > <apex:pageBlockButtons > <apex:commandButton action="{!processSelected}" value="Save"/> </apex:pageBlockButtons> <apex:pageBlockSection title="{!swpnAccount}" > <apex:inputField value="{!getLog.Subject__c}"/> <apex:inputField value="{!getLog.InteractionDate__c}"/> <apex:pageblockSectionItem > <apex:inputField value="{!getLog.Narrative__c}"/> </apex:pageblockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection > <apex:PageBlockTable value="{!AIs}" var="c"> <apex:column headerClass="School" value="{!c.Account__r.Name}"/> <apex:column headerValue="Strategy" value="{!c.Name}"/> <apex:column breakBefore="true" colspan="3"> <apex:outputPanel> <apex:dataTable value="{!actionItems}" var="s"> <apex:column > <apex:inputCheckbox value="{!s.selected}"/> </apex:column> <apex:column headerValue="Name"> {!s.wAI.Name__c} </apex:column> <apex:column headerValue="Status"> {!s.wAI.Status__c} </apex:column> <apex:column headerValue="End Date" width="125"> <apex:outputText value="{0,date,MM-dd-yyyy}"> <apex:param value="{!s.wAI.EndDate__c}"/> </apex:outputText> </apex:column> </apex:dataTable> </apex:outputPanel> </apex:column> <apex:column > <apex:inputCheckbox value="{!c.selected}"/> </apex:column> <apex:column headerValue="Name"> {!c.wAI.Name__c} </apex:column> <apex:column headerValue="Status"> {!c.wAI.Status__c} </apex:column> <apex:column headerValue="End Date" width="125"> <apex:outputText value="{0,date,MM-dd-yyyy}"> <apex:param value="{!c.wAI.EndDate__c}"/> </apex:outputText> </apex:column> </apex:PageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
- aKallNV
- May 31, 2011
- Like
- 0
Another Null Pointer Exception Post. Should be easy.
Hi,
I'm trying to make a page that overides an edit page of a custom object called SchoolWorkPlanLog__c.
This object has a many to many relationship with the nvpsDeployedStrategies__c object and I want to force my users to create at least one Junction Object(StrategyLog__c) record when creating a new SchoolWorkPlanLog__c.
I feel like I'm prettly close, but I'm running into a Null Pointer Exception on Line 24 of controller, which is the first line that references the getLog variable that is declared at the top. It's my understanding of making VF pages that the getLog variable should have all the data provided by the user from the input fields defined in the page, which is the data I want to insert in the processSelected method along with the JunctionObjects.
public with sharing class narrativeWizard_Controller { public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<StrategyLog__c> juncObs { get; set; } public List<cStrats> strategies { get; set; } public List<cStrats> getStrategies() { if(strategies == null) { strategies = new List<cStrats>(); for(nvpsDeployedStrategies__c ds : [select ID, Name, Status__c, Strategy__r.Name, EndDate__c from nvpsDeployedStrategies__c where Account__c = :ApexPages.currentPage().getParameters().get('aID') And Status__c = 'Active']) { strategies.add(new cStrats(ds)); } } return strategies; } public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = ApexPages.currentPage().getParameters().get('aID'), Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c); insert newLog; //insert new Junction Records List<nvpsDeployedStrategies__c> selectedStratys = new List<nvpsDeployedStrategies__c>(); List<StrategyLog__c> newJuncObjs = new List<StrategyLog__c>(); for(cStrats cStrat : getStrategies()) { if(cStrat.selected == true) { selectedStratys.add(cStrat.wDS); } } for(nvpsDeployedStrategies__c ds2 : selectedStratys) { StrategyLog__c newJuncOb = new StrategyLog__c( SchoolWorkPlanNarrative__c = newLog.Id, Strategy__c = ds2.Id); newJuncObjs.add(newJuncOb); } insert newJuncObjs; return null; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.getStrategies(); } public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :ApexPages.currentPage().getParameters().get('aID') Limit 1]; this.swpnAccount = acct.Name; } //wrapper class public class cStrats { public nvpsDeployedStrategies__c wDS { get; set; } public Boolean selected { get; set; } //wrapper class constructor public cStrats(nvpsDeployedStrategies__c c) { wDS = c; selected = false; } } }
<apex:page sidebar="false" showHeader="false" standardController="SchoolWorkPlanLog__c" extensions="narrativeWizard_Controller"> <apex:form > <apex:pageBlock > <apex:pageBlockSection > <apex:commandButton action="{!processSelected}" value="Save"/> <apex:outputText value="{!swpnAccount}"/> </apex:pageBlockSection> <apex:pageBlockSection > <apex:inputField value="{!getLog.Subject__c}"/> <apex:inputField value="{!getLog.Narrative__c}"/> <apex:inputField value="{!getLog.InteractionDate__c}"/> </apex:pageBlockSection> <apex:pageBlockSection > <apex:PageBlockTable value="{!strategies}" var="c"> <apex:column > <apex:inputCheckbox value="{!c.selected}"/> </apex:column> <apex:column headerValue="Name"> {!c.wDS.Strategy__r.Name} </apex:column> <apex:column headerValue="End Date" width="125"> <apex:outputText value="{0,date,MM-dd-yyyy}"> <apex:param value="{!c.wDS.EndDate__c}"/> </apex:outputText> </apex:column> </apex:PageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
- aKallNV
- May 25, 2011
- Like
- 0
Admin needs help with a controller
Hi All,
How do you pass an ID from a lookup field to a controller from a record that hasn't been saved yet?
I have been writing nothing but triggers for a while now, and only have minimal experience with controllers.
Here is what I am trying to do.
SchoolWorkPlanNarrative__c(narrative) has a lookup to the Account Object.
nvpsDeployedStrategy__c(strategy) has a lookup to the Account Object, too.
I have a created junction object between these two objects So that a Narrative record can be tied to more than one Strategy record.
What I want to do is create a VF page that will launch from the Narrative related list on the Account page layout that will allow the user to enter their narrative and then select at least one or as many strategies as there are that belong to the same Account that the Narrative was launched from and insert them as junction object records.
So write away I'm running into trouble...how do I get that Account ID that should be in the lookup field of the Narrative object? I'm confused because it should be there, somewhere, if the New button was clicked from the Account page right? Since the Narrative record has not been saved yet, I'm not sure how to get it.
I have written a little bit so far, and as you can see I don't know how to query for the account.
public with sharing class narrativeWizard_Controller { public String selectedNarrativeID { get; set; } public SchoolWorkPlanNarrative__c selectedNarrative { get; set; } public List<StrategyNarrative__c> juncObs { get; set; } public List<nvpsDeployedStrategy__c> strategies { get; set; } //sets up base list of the available strategies public Set<ID> myStrategies = new Set<ID>(); public void setUPStrategies() { for(nvpsDeployedStrategy__c ds : [select ID from nvpsDeployedStrategy__c where Account__c = ?]) { } } }
- aKallNV
- May 24, 2011
- Like
- 0
Duplicate_Value on Campaign Member Status Trigger
I have written a trigger to standardize Campaign Member Status options. It works great with one exception: it throws a Dupliacte_Value error when I try to Clone a campaign...not sure where to start with debugging.
trigger autoCampaignMemberStatusTrigger on Campaign (after insert) { List<Campaign> newCamps = [select Id, RecordType.Name from Campaign where Id IN :trigger.new AND ParentID = Null AND (RecordType.Name = 'Training' OR RecordType.Name = 'Presentation')]; List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>(); Set<Id> camps = new Set<Id>(); List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>(); List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>(); for(Campaign camp : newCamps){ camps.add(camp.Id); } for(CampaignMemberStatus cm : [select Id, Label, CampaignId from CampaignMemberStatus where CampaignId IN :camps]) { if(cm.Label == 'Sent' || cm.Label == 'Responded') { cms2Delete.add(cm); } CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false, Label = 'Invited', SortOrder = 3, isDefault = true); cms2Insert.add(cms1); CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true, Label = 'Accepted', SortOrder = 4); cms2Insert.add(cms2); CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true, Label = 'Attended', SortOrder = 5); cms2Insert.add(cms3); CampaignMemberStatus cms4 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true, Label = 'Declined', SortOrder = 6); cms2Insert.add(cms4); } insert cms2Insert; delete cms2Delete; }
- aKallNV
- May 12, 2011
- Like
- 0
SOQL query only finding one record when it should be finding several
Select ID, Name, Strategy__c, ActionItem__c, ActionItem__r.Name, ItemNumber__c from nvpsStrategyActionItem__c where Strategy__c IN :stIDs
I am using this query in a soql for loop to create a map. Through testing in the sandbox interface, I am expecting this to return 6 records but it only finds one, which is one of the records it is supposed to find.
Strategy__c is a Lookup field, and stIDs is a list of ids for the object it is looking up to. The query is basically trying to pull all of the child records of a parent record. Can anybody spot why this isn't working correctly?
thanks!
- aKallNV
- April 30, 2011
- Like
- 0
Can't call a future Method from a Future Method
Hi all,
I am trying to create a trigger on the User object that will create a corresponding Contact record and update that Corresponding record when the user record is updated. This has been quite a learning process for me, and I thought I was nearly there when I decided that I should also try to sync the User.Manager field with the Contact.ReportsToId field.
My solution for this was to create a field on the User object to store its corresponding Contact's id, which would allow me to pull the ContactID right from the User record that was chosen to be the Manager and then fed into into the ReportsToId field on the Contact. The challenge is that because this is a User trigger I have annotate the methods with @future. I was hoping that I could update the Users from the same method that Inserted the new Contacts. In other words, when a user is created my trigger would create a new Contact then after that Contact is created the same class would update the User.ContactID__c field with the newly created ContactId. This results in the following error 'System.AsyncException: Future method cannot be called from a future method.'
I then turned to the documentation to find it explicitly stated that this was not possible, and it also stated that it was not possible for an anottated method call a trigger that calls an anottated method. So I guess that rules out creating a second trigger on the Contact object that would update the User object after insert. At this point, I feel like I'm in a conundrum and would appreciate any suggestions.
Thanks,
public with sharing class userHandler {
//this is the method that is triggered by a User Insert, After Insert
@future
public static void createCons(Set<ID> newUs) {
List<User> theNewUs = [select ID, FirstName, LastName,MobilePhone, Email, Department__c, Unit__c, DateofHire__c, TerminationDate__c, Title, Phone from User where ID IN: newUs];
List<Contact> newCons = new List<Contact>();
List<User> userUpdate = new List<User>();
for(User newU : theNewUs) {
Contact theCon = new Contact();
theCon.FirstName = newU.FirstName;
theCon.LastName = newU.LastName;
theCon.Email = newU.Email;
theCon.Department =newU.Department__c;
theCon.Unit__c = newU.Unit__c;
theCon.StartDate__c = newU.DateofHire__c;
theCon.EndDate__c = newU.TerminationDate__c;
theCon.Title = newU.Title;
theCon.Phone = newU.Phone;
TheCon.MobilePhone = newU.MobilePhone;
theCon.AccountId = '001Q000000G7LHh';
theCon.UserId__c = newU.Id;
theCon.ReportsToId = newU.Manager.Contact__c;
newCons.add(theCon);
}
insert newCons;
/*After the new cons are inserted in the line above the following code
updates the User record's ContactID__c field with the newly created ContactID
It is the update statement that throws the no Future method from future method error
because the User Update triggers the next method below called updateCons.*/
List<Contact> aiCons = [select ID, UserId__c from Contact where UserId__c IN :NewUs];
for(User newUUpdate : theNewUs) {
for(Contact aiCon : aicons) {
if(null != aiCon.UserId__c) {
if(aiCon.UserId__c == newUUpdate.Id) {
newUUpdate.ContactID__c = aiCon.Id;
userUpdate.add(newUUpdate);
}
}
}
}
update userUpdate;
}
@future
public static void updateCons(Set<ID> existingUs) {
List<Contact> consUpdate = new List<Contact>();
Map<String,User> idToUser = new Map<String,User>([select ID, FirstName, LastName, Email, Manager.ContactID__c, Department__c, Unit__c, DateofHire__c, TerminationDate__c, Title, Phone, MobilePhone from User where ID IN: existingUs]);
for(Contact existingCon : [select ID, FirstName, LastName, Email, ReportsToId, Department, Unit__c, StartDate__c, EndDate__c, Title, Phone, MobilePhone, UserID__c from Contact where userID__c IN :idToUser.keySet()]) {
if(existingCon.FirstName != idToUser.get(existingCon.UserID__c).FirstName) {
existingCon.FirstName = idToUser.get(existingCon.UserID__c).FirstName;
}
if(existingCon.LastName != idToUser.get(existingCon.UserID__c).LastName) {
existingCon.LastName = idToUser.get(existingCon.UserID__c).LastName;
}
if(existingCon.Email != idToUser.get(existingCon.UserID__c).Email) {
existingCon.Email = idToUser.get(existingCon.UserID__c).Email;
}
if(existingCon.Department != idToUser.get(existingCon.UserID__c).Department__c) {
existingCon.Department = idToUser.get(existingCon.UserID__c).Department__c;
}
if(existingCon.Unit__c != idToUser.get(existingCon.UserID__c).Unit__c) {
existingCon.Unit__c = idToUser.get(existingCon.UserID__c).Unit__c;
}
if(existingCon.StartDate__c != idToUser.get(existingCon.UserID__c).DateofHire__c) {
existingCon.StartDate__c = idToUser.get(existingCon.UserID__c).DateofHire__c;
}
if(existingCon.EndDate__c != idToUser.get(existingCon.UserID__c).TerminationDate__c) {
existingCon.EndDate__c = idToUser.get(existingCon.UserID__c).TerminationDate__c;
}
if(existingCon.Title != idToUser.get(existingCon.UserID__c).Title) {
existingCon.Title = idToUser.get(existingCon.UserID__c).Title;
}
if(existingCon.MobilePhone != idToUser.get(existingCon.UserID__c).MobilePhone) {
existingCon.MobilePhone = idToUser.get(existingCon.UserID__c).MobilePhone;
}
if(existingCon.phone != idToUser.get(existingCon.UserID__c).phone) {
existingCon.phone = idToUser.get(existingCon.UserID__c).phone;
}
//system.assert(false, 'haha '+existingCon.ReportsToId + ' ' + idToUser.get(existingCon.UserID__c).Manager.ContactID__c);
if(null != existingCon.ReportsToId && (existingCon.ReportsToId != idToUser.get(existingCon.UserID__c).Manager.ContactID__c)) {
existingCon.ReportsToId = idToUser.get(existingCon.UserID__c).Manager.ContactID__c;
}
consUpdate.add(existingCon);
}
update consUpdate;
}
}
- aKallNV
- April 06, 2011
- Like
- 0
Looking for an opportunity to get better at writing code.
Hi All,
I am an administrator who wants to learn Apex and VF. I took the Advanced developer course about two years ago, and have had intermittent opportunities to write code since then, which usually results in me posting to these boards looking for help.
I have just learned that my dept. has a little money available for Professional Development. Since, I have already taken the Advanced dev course, I am not intersted in taking it again. Although, I probably would get a lot more out of it this time. I noticed there is now a course called 'Object Oriented Programing with Apex'. The title of this class interestes me because I have no coding background. All of my understanding of OO concepts has been learned from reading java books and Jason Ouellete's book, but I don't want to sit through a week of concept instruction to build a 'Hello World' app. Has anybody taken either of these classes recently, and could they give any opinions on them?
Also, in the past, I have run into some folks that have tried to make a business out of teaching Apex. However, I haven't seen them on the boards in a while, and can't remember their names. So, I'm curious to know if there is anybody out there who has tried them and to know what they thought of it.
And finally, I will just throw this out there...anybody in the NYC area willing to be an Apex mentor?
Thanks,
Andy
- aKallNV
- March 28, 2011
- Like
- 0
problem with SOQL Bind
Need help with the following SOQL statement:
List<Contact> existingCons = [select ID, FirstName, LastName, Email, Department, Unit__c, StartDate__c, EndDate__c, Title, Phone from Contact where userID__c != null AND userID__c IN :idToUser.keySet()];
Here's the deal. This query isn't returning any records when it should be returning one. I know that it should be returning one because I know there is currently only one record because I am using the interface to trigger this code. I have used system.debug to confirm this. So the following
system.debug(idToUser.keySet());
returns the expected value, which is just an SF ID for the User object.
when I query directly for the id...like this
List<Contact> existingCons = [select ID, FirstName, LastName, Email, Department, Unit__c, StartDate__c, EndDate__c, Title, Phone from Contact where userID__c != null AND userID__c ='005Q0000000W6xbIAC'];
The record is found as expected. That ID is the exact Id that is returned by the system.debug.
Does anybody see what I'm doing wrong?
Thanks!
- aKallNV
- March 24, 2011
- Like
- 0
Mixed DML error on Trigger that is only inserting and updating Contact object
I have found some info out there about Mixed_DML errors, but most of them have to do with Controllers and action chaining for VF pages.
I am getting one on a trigger that attempts to do the following:
Up until this point every employee gets a seat in our SFDC org. We also make a Contact record for every employee to record cases, training etc. Therefore, I wanted to make a trigger that created a Contact whenever a new User record is created or upates the Contact whenever the corresponding User is edited. So the following is what I started with. The logic isn't complete, but there is enough there to get started. Anyway. it's giving me the following when I try to test by creating a new user in the interface.
MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): Contact, original object: User: []
What I'm confused by(take warning here, I'm a completely self-taught novice and struggling) is that the docs say that mixed dml errors occur because a single method is trying to manipulate two different sObjects, and that the solution is to have the two dml statements in two different methods one of which is tagged with @future. However, I am only trying to run DML on the Contact object, so what's the deal?
BTW, I'm totally open to people making suggestions on how to make this code more efficient, elegant etc.
Thanks!
trigger userTrigger on User (after insert, after update) { List<Contact> newCons = new List<Contact>(); List<Contact> exCons = new List<Contact>(); if(trigger.isInsert) { for(User newU : trigger.new) { Contact theCon = new Contact(); theCon.FirstName = newU.FirstName; theCon.LastName = newU.LastName; theCon.Email = newU.Email; theCon.Department =newU.Department__c; theCon.Unit__c = newU.Unit__c; theCon.StartDate__c = newU.DateofHire__c; theCon.EndDate__c = newU.TerminationDate__c; theCon.Title = newU.Title; theCon.Phone = newU.Phone; theCon.AccountId = '001Q000000G7LHh'; newCons.Add(theCon); } } insert newCons; if(trigger.isUpdate) { List<Contact> existingCons = [select ID, FirstName, LastName, Email, Department, Unit__c, StartDate__c, EndDate__c, Title, Phone from Contact where Id IN :trigger.newMap.keySet()]; for(Contact existingCon : existingCons) { if(existingCon.FirstName != trigger.newMap.get(existingCon.Id).FirstName) { existingCon.FirstName = trigger.newMap.get(existingCon.Id).FirstName; } if(existingCon.LastName != trigger.newMap.get(existingCon.Id).LastName) { existingCon.LastName = trigger.newMap.get(existingCon.Id).LastName; } if(existingCon.Email != trigger.newMap.get(existingCon.Id).Email) { existingCon.Email = trigger.newMap.get(existingCon.Id).Email; } if(existingCon.Department != trigger.newMap.get(existingCon.Id).Department__c) { existingCon.Department = trigger.newMap.get(existingCon.Id).Department__c; } if(existingCon.Unit__c != trigger.newMap.get(existingCon.Id).Unit__c) { existingCon.Unit__c = trigger.newMap.get(existingCon.Id).Unit__c; } if(existingCon.StartDate__c != trigger.newMap.get(existingCon.Id).DateofHire__c) { existingCon.StartDate__c = trigger.newMap.get(existingCon.Id).DateofHire__c; } if(existingCon.EndDate__c != trigger.newMap.get(existingCon.Id).TerminationDate__c) { existingCon.EndDate__c = trigger.newMap.get(existingCon.Id).TerminationDate__c; } if(existingCon.Title != trigger.newMap.get(existingCon.Id).Title) { existingCon.Title = trigger.newMap.get(existingCon.Id).Title; } if(existingCon.phone != trigger.newMap.get(existingCon.Id).phone) { existingCon.phone = trigger.newMap.get(existingCon.Id).phone; } //newCons.add(existingCon); } } update exCons; }
- aKallNV
- March 22, 2011
- Like
- 0
Custom Button not passing ID
hi,
I have a custom button that I use to pass two id's to a controller. The button allows me to launch a VF page from a related list. This button was working fine, but has suddenly started throwing an invalid id error. My first assumption was that it had to do with the introduction of a new record type, which was causing an error in my controller somewhere, but I quickly noticed that the button was setting up the URL incorrectly. So, the button is meant to pass two ids one for custom object Goal__c and another for Account, and their query string variables are gid and aid, respectively. I noticed that when I click the button and get the error message that aid does not have the account's id assigned, and the error message points me to first line of code that works with account id. To further confuse things, I have buttons that work in a very similar matter, but they are launched from a different object, but still rely on account id in the same way...these still work fine. So, I'm curious to know if anybody has any ideas on why this might be failing.
Here is url that the button sets up: /apex/narrativeWizard3?gID={!Goal__c.Id}&aID={!Account.Id}
- aKallNV
- October 17, 2011
- Like
- 0
Formula field not evaluating in test class
I have a formula field called 'Status' that assigns a Status to a record based on the value provided in a date field on the same record. Simply put the logic is: If Start Date is not null then Status equals 'Priority'. Otherwise Status equals 'Inactive'.
I have tested this pretty thouroughly in the UI and haven't found any problems.
I am using this object in a VF controller and I need to test both conditions...the records that are a Priority and the records that are Inactive. So my test inserts a bunch of records without a Start Date which means that none of them would be a Priority. I then try to update some of those records with a Start Date to test the other condition. Here is where I am running into trouble. For some reason, the formula is not evaluated. I have verified with system.debug that although there is a Start Date present on the records the Status field is still 'Inactive'.
Does anybody know why the formula field would not fire in a test method?
- aKallNV
- August 13, 2011
- Like
- 0
VF controller: Why aren't two of several fields being saved?
The code posted below is a small portion of a VF controller. This portion is part of a Save Method that inserts a new record in a custom object. I have had this working fine for a few weeks now. However, I was just provided a new business need, which is simply the addition of two new fields. For some reason the data in these fields are not being inserted. All of the other fields are being saved just fine. The two new fields are callled CategoryofWork__c and HoursSpent__c. They are simply a picklist field and an integer field. I can't spot any difference between them and the other fields that would prevent them from being inserted. No errors are thrown. The record simply saves without the data.
Any ideas?
Thanks!
//Method called by Save Button public PageReference processSelected() { //insert new Log SchoolWorkPlanLog__c newLog = new SchoolWorkPlanLog__c( Account__c = accountID, Subject__c = this.getLog.Subject__c, Narrative__c = this.getLog.Narrative__c, InteractionDate__c = this.getLog.InteractionDate__c, CategoryofWork__c = this.getLog.CategoryofWork__c, HoursSpent__c = this.getLog.HoursSpent__c, Category__c = this.getLog.Category__c, OffPlan__c = this.getLog.OffPlan__c, Department__c = this.getLog.Department__c, Unit__c = this.getLog.Unit__c ); insert newLog;
- aKallNV
- August 11, 2011
- Like
- 0
Table rows repeating for each Child Record present in Parent to Child Query
Hi all,
This method populates a pageblockTble that I have built which groups child records by their parent records. I have a simpler version of this method that works fine. However, just got the need for some new logic, and now I'm struggling. The request requires me to provide two different iists based on criteria in the Child records. The problem is that I'm getting repeating values for each child object. For example, if there are 3 child objects then I see the group of 3 child Objects and its parent repeated 3 times in the table. I understand why this is happening. I have comments to code below to explain.
thanks!
public void makesStrategyWrappers() { theDSs = new List<DeployedStrategy__c>(); theVFDSs = new List<DeployedStrategy__c>();//I use this variable in my VF page as a map key for grouping the child objects List<cAIS> cAIS1 = new List<cAIS>(); theWrappers = new List<cAIS>(); theWrapperMap = new Map<Id, List<cAIS>>(); String queryString = this.getStrategyQuery(); theDSs = Database.query(queryString); if(theDSs.size() > 0) { for(DeployedStrategy__c ds : theDSs) { if(ds.DeployedActionItem__r.size() > 0) { for(DeployedActionItems__c actI : ds.DeployedActionItem__r) { if(actI.Status__c == 'Priority' && actI.Stage__c != 'Completed' && !this.showAll) { theVFDSs.add(ds); //here is where I populate the key. The values repeat because for each child that Iterate //through it adds the same key parent value. How do I populate this with just unique ideas. I tried a set but that just seems to throw errors. cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } if(this.showAll){ theVFDSs.add(ds); cAIS1 = theWrapperMap.get(ds.Id); if(null == cAIS1) { cAIS1 = new List<cAIS>(); theWrappers.add(new cAIS(actI)); theWrapperMap.put(ds.Id, cAIS1); } cAIS1.add(new cAIS(actI)); } } } } } }
- aKallNV
- August 05, 2011
- Like
- 0
Struggling with ajax
In fact, struggling with a lot...this is like the eleventeenth post I've made on this page and controller...it just keeps getting bigger. Anyway, here is the situation. I have a datatable that I want to allow users to filter with two different picklists, which are called Unit and Principle. The datatables are reRendered based on dynamic soql queries generated by what they select from the filter picklists, and the constructor is set up so that the page defaults to be filtered to only record's in the User's Unit and All Principles. The user has to select the combination of Unit and Principle that they want and then click a Filter button to get a different view. I actually have all that working.
The part that I am struggling with is getting the two picklist values to reRender. The Unit that a User selects should change the available Principles to select from and vice versa. So I am trying to use dynamic soql for this too. There were points in my playing around with it that it kind of worked...it would work up until the first time I clicked the filter button, but then anytime after it just pulled all values, and now it's just pulling all Values, and I can't get back to the partial success I was having. I'm pretty lost and tired at this point, so I am just going to throw the code out there to see if any of you has any ideas or opinions. Thanks!
BTW, I am not going to post the entire controller or page because they are getting pretty long.
public with sharing class narrativeWizard_Controller { public String accountID; public String swpnAccount { get; set; } public SchoolWorkPlanLog__c getLog { get; set; } public List<UniversalJoin__c> juncObs { get; set; } public List<cAIS> theWrappers { get; set; } public Map<ID,List<cAIS>> theWrapperMap { get; set; } public List<DeployedStrategy__c> theDSs { get; set; } public List<Goal__c> theGoals { get; set; } public List<cGS> theGoalWrappers { get; set; } public Set<String> unitOptions = new Set<String>(); public String selectedUnit { get; set; } public Set<String> princyOptions = new Set<String>(); public String selectedPrincy { get; set; } //public Set<String> catyOptions = new Set<String>(); //public String selectedCaty { get; set; } public List<cCONS> theConWrappers { get; set; } public List<cCASES> theCaseWrappers { get; set; } public String unitFilter { get; set; } public Set<String> goalUnitOptions = new Set<String>(); public String selectedGoalUnit { get; set; } //sets up class extension of SchoolWorkPlanLog__c private final SchoolWorkPlanLog__c swpn; //CONSTRUCTOR public narrativeWizard_Controller(ApexPages.StandardController swpnController) { this.accountID = ApexPages.currentPage().getParameters().get('aID'); this.swpn = (SchoolWorkPlanLog__c)swpnController.getRecord(); this.setUpAccount(); this.makesStrategyWrappers(); this.makesGoalWrappers(); this.makesContactWrappers(); this.makesCaseWrappers(); this.getLog= new SchoolWorkPlanLog__c(); this.setUpUnitFilter(); this.selectedUnit = setUpUnitFilter(); this.selectedGoalUnit = setUpUnitFilter(); this.getAllStrategyUnits(); this.getStratyPrincys(); this.getAllGoals(); } //pulls the Account from which the Log was initiated. public void setUpAccount() { Account acct = [select ID, Name from Account where ID = :accountID Limit 1]; this.swpnAccount = acct.Name; } //pulls the user who initiated the log so that lists can be filtered to the Unit they belong to. public String setUpUnitFilter() { ID UP = Userinfo.getUserId(); User userX = [select ID, Name, Department__c, Unit__c from User where ID =:UP]; return userX.Unit__c; } //pulls all Strategies to generate inital list of Unit options. public void getAllStrategyUnits() { for(DeployedStrategy__c aDS : [select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = 'Active']) { unitOptions.add(aDS.Unit__c); } } //generates query strings to pull Unit Options based on the Princple that was chosen. public void getStratyUnits() { List<DeployedStrategy__c> theDSs2= new List<DeployedStrategy__c>(); String queryString2; if(this.selectedPrincy != 'All') { queryString2 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\' and Principle__c =:selectedPrincy'; } if(this.selectedPrincy == 'All') { queryString2 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''; } theDSs2 = Database.query(queryString2); for(DeployedStrategy__c aDS : theDSs2) { unitOptions.add(aDS.Unit__c); } } public void getStratyPrincys() { List<DeployedStrategy__c> theDSs3= new List<DeployedStrategy__c>(); String queryString3; if(this.selectedUnit != 'All') { queryString3 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\' AND Unit__c =:selectedUnit'; } if(this.selectedUnit == 'All') { queryString3 = 'select ID, Name, Principle__c, Category__c, Unit__c from DeployedStrategy__c where Account__c = :accountID And Status__c = \'Active\''; } theDSs3 = Database.query(queryString3); for(DeployedStrategy__c aDS : theDSs3) { princyOptions.add(aDS.Principle__c); } }
<apex:pageBlock id="pb2"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:commandButton action="{!processSelected}" value="Save" style="left:300px;position:relative;" /> <apex:commandButton action="{!cancelButton}" value="Cancel" style="left:310px;position:relative;"/> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Select the Work Plans, Goals, Cases and Contacts that this Entry pertains to." collapsible="false" rendered="{!showAIandGoal}" columns="1"> <apex:tabPanel switchType="client" selectedTab="tab1" > <apex:tab label="Work Plans" id="tab1"> <apex:pageBlockSection collapsible="false" columns="3"> <apex:pageBlockSectionItem > <apex:outputLabel value="Filter by Unit"/> <apex:selectList value="{!selectedUnit}" size="1" id="uniList"> <apex:selectOptions value="{!Units}"/> <apex:actionSupport event="onchange" reRender="princyList" action="{!getStratyPrincys}" status="UnitStatus" /> <apex:actionStatus id="UnitStatus" startText="Fetching Principles..."/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel value="Filter by Principle"/> <apex:selectList value="{!selectedPrincy}" size="1" id="princyList"> <apex:selectOptions value="{!Princys}"/> <apex:actionSupport event="onchange" reRender="uniList" action="{!getStratyUnits}" status="PrincyStatus"/> <apex:actionStatus id="PrincyStatus" startText="Fetching Principles..."/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:commandButton action="{!makesStrategyWrappers}" reRender="table1" value="Filter"> <apex:actionSupport event="onchange" status="UnitStatus"/> <apex:actionStatus id="UnitStatus" startText="Fetching Records..."/> </apex:commandButton> </apex:pageBlockSectionItem>
- aKallNV
- July 13, 2011
- Like
- 0
Mixed DML error on Trigger that is only inserting and updating Contact object
I have found some info out there about Mixed_DML errors, but most of them have to do with Controllers and action chaining for VF pages.
I am getting one on a trigger that attempts to do the following:
Up until this point every employee gets a seat in our SFDC org. We also make a Contact record for every employee to record cases, training etc. Therefore, I wanted to make a trigger that created a Contact whenever a new User record is created or upates the Contact whenever the corresponding User is edited. So the following is what I started with. The logic isn't complete, but there is enough there to get started. Anyway. it's giving me the following when I try to test by creating a new user in the interface.
MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): Contact, original object: User: []
What I'm confused by(take warning here, I'm a completely self-taught novice and struggling) is that the docs say that mixed dml errors occur because a single method is trying to manipulate two different sObjects, and that the solution is to have the two dml statements in two different methods one of which is tagged with @future. However, I am only trying to run DML on the Contact object, so what's the deal?
BTW, I'm totally open to people making suggestions on how to make this code more efficient, elegant etc.
Thanks!
trigger userTrigger on User (after insert, after update) { List<Contact> newCons = new List<Contact>(); List<Contact> exCons = new List<Contact>(); if(trigger.isInsert) { for(User newU : trigger.new) { Contact theCon = new Contact(); theCon.FirstName = newU.FirstName; theCon.LastName = newU.LastName; theCon.Email = newU.Email; theCon.Department =newU.Department__c; theCon.Unit__c = newU.Unit__c; theCon.StartDate__c = newU.DateofHire__c; theCon.EndDate__c = newU.TerminationDate__c; theCon.Title = newU.Title; theCon.Phone = newU.Phone; theCon.AccountId = '001Q000000G7LHh'; newCons.Add(theCon); } } insert newCons; if(trigger.isUpdate) { List<Contact> existingCons = [select ID, FirstName, LastName, Email, Department, Unit__c, StartDate__c, EndDate__c, Title, Phone from Contact where Id IN :trigger.newMap.keySet()]; for(Contact existingCon : existingCons) { if(existingCon.FirstName != trigger.newMap.get(existingCon.Id).FirstName) { existingCon.FirstName = trigger.newMap.get(existingCon.Id).FirstName; } if(existingCon.LastName != trigger.newMap.get(existingCon.Id).LastName) { existingCon.LastName = trigger.newMap.get(existingCon.Id).LastName; } if(existingCon.Email != trigger.newMap.get(existingCon.Id).Email) { existingCon.Email = trigger.newMap.get(existingCon.Id).Email; } if(existingCon.Department != trigger.newMap.get(existingCon.Id).Department__c) { existingCon.Department = trigger.newMap.get(existingCon.Id).Department__c; } if(existingCon.Unit__c != trigger.newMap.get(existingCon.Id).Unit__c) { existingCon.Unit__c = trigger.newMap.get(existingCon.Id).Unit__c; } if(existingCon.StartDate__c != trigger.newMap.get(existingCon.Id).DateofHire__c) { existingCon.StartDate__c = trigger.newMap.get(existingCon.Id).DateofHire__c; } if(existingCon.EndDate__c != trigger.newMap.get(existingCon.Id).TerminationDate__c) { existingCon.EndDate__c = trigger.newMap.get(existingCon.Id).TerminationDate__c; } if(existingCon.Title != trigger.newMap.get(existingCon.Id).Title) { existingCon.Title = trigger.newMap.get(existingCon.Id).Title; } if(existingCon.phone != trigger.newMap.get(existingCon.Id).phone) { existingCon.phone = trigger.newMap.get(existingCon.Id).phone; } //newCons.add(existingCon); } } update exCons; }
- aKallNV
- March 22, 2011
- Like
- 0
Trigger Help Please - Using AggregateResult to Compare Values
Good morning, I am hoping someone can set me straight on what I am attempting to do here.
- I have a custom object Work Order that has a lookup relationship to Opportunity.
- There can be many Work Orders related to one opportunity.
- On Opportunity, I have a custom field that is populated via a trigger to count all of the Work Orders associated
I have a second trigger that is meant to
- identify those Work Orders that are closed and,
- if the count of Closed Work Orders = the count of all Work Orders
- update the Opportunity Stage to Completed
I am getting lost on how to write the logic to compare the COUNT of the closed Work Orders to the value in the Opportunity field. I'd appreciate any help!!! Thanks.
trigger trigWorkorderCloseOpp on Work_Order__c (after insert, after update) { //************************************************ // Build a LIST of Opportunity ID's that may // need closing //************************************************ set <id> oppIDs = new set <id>(); list <Opportunity> opportunity = [SELECT ID FROM Opportunity WHERE ID in:oppIDs]; if(Trigger.isInsert || Trigger.isUpdate){ for(Work_Order__c w : trigger.new){ if(w.Opportunity__c != null && w.stage__c == 'Work Order Closed - Quickbooks') {oppIDs.add(w.Opportunity__c); } else if (w.Opportunity__c != null && w.stage__c == 'Job Completed') {oppIDs.add(w.Opportunity__c); } } // INSERT/UPDATE Trigger if(Trigger.isDelete || Trigger.isUpdate){ for(Work_Order__c w : trigger.old){ if(w.Opportunity__c != null && w.stage__c == 'Work Order Closed - Quickbooks') {oppIDs.add(w.Opportunity__c); } else if (w.Opportunity__c != null && w.stage__c == 'Job Completed') {oppIDs.add(w.Opportunity__c); } } } if(oppIDs .size() > 0) { Map<ID, Opportunity> oppMap = new Map<ID, Opportunity>([Select id, WO_Count__c, StageName from Opportunity Where Id in :oppIds]); Opportunity d = null; for (AggregateResult ar : [SELECT ID, Opportunity__c, COUNT(Id)total FROM Work_Order__c WHERE Opportunity__c in: oppIds GROUP BY Opportunity__c]) { String dID = (String)dr.get('Opportunity__c'); Integer a = Integer.valueOf(ar.get('total')); if(oppMap.get(dID) == null) d = new Opportunity(ID=string.valueOf(ar.get('Opportunity__c'))); else if(oppMap.containskey(dID)&& a.equals(Opportunity.WO_Count__c)) d = oppMap.get(dID); } d = opps.get(dID); d.StageName = 'Job Completed'; update opps.values(); } } }
- pmozz01
- July 12, 2010
- Like
- 0
Formula Fields Not Evaluating when Running testmethod
Hello,
I have an issue where I have conditional logic in a trigger that is based on the value of a formula field. When running a functional test in the UI, this formula field evaluates fine and the trigger logic proceeds as expected. When I run a testmethod with the same use case, the formula field does not evaluate and a bunch of code doesn't get covered.
This is happening in two separate places in two different orgs. I also have the debug logs to prove the formula field is getting evaluated in the functional test and not getting evaluated in the testmethod.
Has anyone ever run into this issue? If so, how do you get around it without rewriting the trigger to mimic the formula field logic?
Thanks very much for any input!
- EchoMarc
- July 22, 2009
- Like
- 0