-
ChatterFeed
-
1Best Answers
-
0Likes Received
-
0Likes Given
-
26Questions
-
17Replies
Custom object field update trigger
I have a custom object (object__c) into which records are being bulk uploaded/inserted. There is a particular field on this object (appt__c) that includes a code (sometimes abbreviated text, sometimes alphanumeric, etc.) that corresponds to an appointment type.
I am trying to update a second field on the record (text__c) with a more "readable" text-version of the appointment type. For example, if "ov" is uploaded into the appt__c field, I want to update the text__c field with "office visit." There usually will be, however, multiple codes that correspond with the same text version. For example, all of the following might equal "office visit": "ov," "ov(15)," "office."
This seems like a relatively simple issue, but I can't seem to get to the answer. Anyone willing to offer any suggestions?
(p.s. I am currently doing this with a field replacement workflow, but there are so many apppointment type codes that I keep running up against limits in my field update formula.)
- PaulJS
- January 26, 2014
- Like
- 0
Require Data Category selection in order to publish an article
- RossG
- January 27, 2015
- Like
- 0
Find date a field was last populated
I know there's an app called Field Trip that will tell you how many records havea givern object's field populated for each field in that object.
Is there an app or someother way to determine the date upon which a given object's field was last populated though?
- RossG
- January 20, 2015
- Like
- 0
Sorting on apex:pageblocktable columns
Is there a way to make the columns in this visualforce page sortable? It's simply a page that displays the open tasks owned by the current user.
controller:
public class tasksController{ List<Task> tk; // toggles the sorting of query from asc<-->desc public tasksController(ApexPages.StandardController Controller){ } public List<Task> getResults(){ return tk; } public PageReference gettk(){ String userId=UserInfo.getUserId(); UserId=userId.Substring(0,15); tk=[Select Status, Subject, Priority, OwnerId, Owner.Name, WhatId, Response_Needed__c,What.Name, WhoId, Who.Name, ActivityDate from Task WHERE Status != 'Completed' AND (ActivityDate = THIS_WEEK ) AND OwnerId =: UserId ORDER BY ActivityDate DESC LIMIT 25 ]; return Null; } }
visualforce page:
<apex:page standardController="Task" extensions="tasksController" action="{!gettk}"> <apex:form > <html> <img src="/img/icon/home32.png"/> <font size="5"> My Open Tasks Due This Week</font><br></br> <apex:pageblock > <apex:pageBlockTable value="{!results}" var="tsk"> <apex:column > <apex:outputlink value="/{!tsk.Id}">{!tsk.Subject}</apex:outputLink> <apex:facet name="header"> Subject </apex:facet> </apex:column> <apex:column > <apex:outputField value="{!tsk.Response_Needed__c}" /> <apex:facet name="header"> Urgency <span class="helpButton" id="example-title-_help"> <img src="/s.gif" class="helpOrb"/> <script type="text/javascript"> sfdcPage.setHelp('example-title', 'RED: Task is overdue by 1 day or more or has no due date. YELLOW: Task is due today. GREEN: Task is due on some day in the future. '); </script> </span> </apex:facet> </apex:column> <apex:column > <apex:outputLink value="/{!tsk.WhoId}">{!tsk.Who.Name}</apex:outputLink> <apex:facet name="header"> Name</apex:facet> </apex:column> <apex:column > <apex:outputLink value="/{!tsk.OwnerId}">{!tsk.Owner.Name}</apex:outputLink> <apex:facet name="header"> Assigned To </apex:facet> </apex:column> <apex:column value="{!tsk.ActivityDate}"/> <apex:column value="{!tsk.Status}"/> </apex:pageBlockTable> <br></br> <apex:outputLink target="_blank" value="https://cs15.salesforce.com/00Oe0000000Ta99" id="theLink">View All My Open Tasks</apex:outputLink> </apex:pageblock> </html> </apex:form> </apex:page>
- RossG
- December 16, 2014
- Like
- 0
too many soql queries error
if(Trigger.isInsert || Trigger.isUpdate){ if(HelperClass.firstRun2){ HelperClass.firstRun2=false; for(Lead l1: trigger.new){ if((UserInfo.getUserId() == Label.MarketoIntegrationUser || UserInfo.getUserId() == Label.WebsiteIntegrationUser) && (l1.RecordTypeId == leadRecordTypeId) && (l1.Country == 'United States' || l1.Country == 'United States of America' || l1.Country == 'USA' || l1.Country == 'U.S.' || l1.Country == 'U.S.A' ) ){ Set<String> postalCodes = new Set<String>(); for( Lead l : trigger.new ) { if(l.PostalCode != null && l.PostalCode.length() >=5) try{ String zipStringx = l.PostalCode.substring(0,5); postalCodes.add( zipStringx ); // postalCodes.add( l.PostalCode ); } catch(DMLException e){ ApexPages.addMessages(e); Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {'sfdc-admins@pingidentity.com'}; mail.setToAddresses(toAddresses); mail.setReplyTo('sfdc-admins@pingidentity.com'); mail.setSenderDisplayName('Apex error message'); mail.setSubject('Error from Org : ' + UserInfo.getOrganizationName()); mail.setPlainTextBody(e.getMessage()); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } } Map<String, Zip_State_Table__c > validZips = new Map<String, Zip_State_Table__c >(); for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); } for( Lead l : trigger.new ) { if( l.PostalCode != null && l.PostalCode.length() >=5 ) { if( validZips.containsKey(l.PostalCode.substring(0,5)) ) { l.State = validZips.get(l.PostalCode.substring(0,5)).Name; l.RegionTerritoryHidden__c = validZips.get(l.PostalCode.substring(0,5)).Territory__c; } else {} } } } } } }
I know the error in the above code is with this part of the code:
for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); }
I'm unable to re-write that code to avoid the error. Does anyone see how I can re-write that code with the soql query for loop to avoid the too many soql queries error? Thanks
- RossG
- December 03, 2014
- Like
- 0
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: LeadTrigger: execution of BeforeUpdate caused by: System.StringException: Ending position out of bounds: 5 Trigger.LeadTrigger: line 58, column 1\n
The offending line is in the code below where it says:
String zipStringx = l.PostalCode.substring(0,5);
Does anyone know how I could tweak this code to prevent that error? Thanks. Here's the full code for hte lead trigger where this occurs:
/*Begin Processing United States leads*/ if(Trigger.isInsert || Trigger.isUpdate){ if(HelperClass.firstRun2){ HelperClass.firstRun2=false; for(Lead l1: trigger.new){ if((UserInfo.getUserId() == Label.MarketoIntegrationUser || UserInfo.getUserId() == Label.WebsiteIntegrationUser) && (l1.RecordTypeId == leadRecordTypeId) && (l1.Country == 'United States' || l1.Country == 'United States of America' || l1.Country == 'USA' || l1.Country == 'U.S.' || l1.Country == 'U.S.A' ) ){ Set<String> postalCodes = new Set<String>(); for( Lead l : trigger.new ) { if(l.PostalCode != null){ String zipStringx = l.PostalCode.substring(0,5); postalCodes.add( zipStringx ); // postalCodes.add( l.PostalCode ); } else{} } Map<String, Zip_State_Table__c > validZips = new Map<String, Zip_State_Table__c >(); for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); } for( Lead l : trigger.new ) { if( l.PostalCode != null ) { if( validZips.containsKey(l.PostalCode.substring(0,5)) ) { l.State = validZips.get(l.PostalCode.substring(0,5)).Name; l.RegionTerritoryHidden__c = validZips.get(l.PostalCode.substring(0,5)).Territory__c; } else {} } } } } } }
- RossG
- November 10, 2014
- Like
- 0
attempt to de-reference a null object error
This is a visualforce page with custom controller that is basically a custom product picker on opportunity object. The error I get when trying to add a product to the opp is:
Attempt to de-reference a null object
Error is in expression '{!modifyRecord}' in page manage_products: Class.ManageProductsController.modifyRecord: line 324, column 1
Does anyone see anything in this code below that could be causing the error?
public class ManageProductsController { /* Controller for "Manage Products" Visualforce Page, aka the "product picker" */ // Declare static variables private static final Map<String,String> PRODUCT_FILTER_VALUES_MAP; private static final Set<String> COREBLOX_PRODUCT_CODES = new Set<String>{'CBWK-H-PUL','PE-CS-CBWS'}; private static final Set<String> VALID_CHOICES_SET = new Set<String>{ 'CIC','CK','SC','TT' }; private static final Set<Id> ADMIN_PROFILE_ID_SET; // Which profiles can use product picker to edit won Opps private static final string PICKLIST_DEFAULT = 'All'; //defailt picklist value // Declare public class variables public Boolean editAfterClosed { get { return (editAfterClosed == null) ? false : editAfterClosed; } set; } public Boolean showAddProductsPanel { get { return (showAddProductsPanel == null) ? false : showAddProductsPanel; } set; } public String action { get; set; } public String productFilter { get; set; } public String useCase { get; set; } public String capability { get; set; } public String license { get; set; } public String upToQuantity { get; set; } public Id currentOliId { get; set; } public Opportunity currentOpp { get; set; } public List<OpportunityLineItem> oliExistingList { get; set; } public List<OpportunityLineItem> oliPickerList { get; set; } public List<PricebookEntry> pbeListActive { get; set; } public List<SelectOption> productFilterValues { get; set; } public Map<Id,Decimal> pbeCalculableSupportProductMap { get; set; } public Map<Id,String> pbeProductCodeMap { get; set; } public Map<Id,String> pbeProductNameMap { get; set; } public Map<Id,OpportunityLineItem> oliDetailsMap { get; set; } // Declare private class variables private ApexPages.StandardController stdController; private List<OpportunityLineItem> oliNewList = new List<OpportunityLineItem>(); private List<PricebookEntry> pbeListAll = new List<PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapAll = new Map<Id,PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapActive = new Map<Id,PricebookEntry>(); // Instantiate static variables static { ADMIN_PROFILE_ID_SET = new Set<Id>{ '00e40000000rTp1', // Custom Contract Admin '00e30000000bzB3' // System Administrator }; PRODUCT_FILTER_VALUES_MAP = new Map<String,String>{ 'All' => 'All', 'Bundles' => 'CB', 'Cloud Identity Connector' => 'CIC', 'Commercial Integration Kit' => 'CK', 'Connection Based' => 'CONN', 'CoreBlox' => 'CoreBlox', 'Discount' => 'Cust', 'ELA' => 'ELA', 'Endpoint' => 'EP', 'Oauth Add-on' => 'OAA', 'Oauth Standalone' => 'OAS', 'PingAccess' => 'PA', 'PingConnect' => 'PC', 'PingEnable Consulting' => 'PE', 'PingFed Server' => 'PFS', 'PingOne' => 'PO', 'PingEnable Training' => 'PT', 'Saas Program Bundle' => 'Saas', 'SaaS Connector' => 'SC', 'STS Add-on' => 'SSA', 'STS Standalone' => 'SSS', 'Support' => 'SUP', 'Token Translator' => 'TT', 'WAM Integration Kit' => 'WMIK', 'WAM Token Translator' => 'WMTT' }; } /* Constructor */ public ManageProductsController(ApexPages.StandardController stdController) { // Instantiate class variables this.stdController = stdController; currentOpp = (Opportunity)stdController.getRecord(); editAfterClosed = false; // Default value if (ADMIN_PROFILE_ID_SET.contains(UserInfo.getProfileId())) { editAfterClosed = true; } productFilterValues = new List<SelectOption>(); for (String s : PRODUCT_FILTER_VALUES_MAP.keySet()) { productFilterValues.add(new SelectOption(PRODUCT_FILTER_VALUES_MAP.get(s),s)); } productFilterValues.sort(); oliDetailsMap = new Map<Id,OpportunityLineItem>(); oliExistingList = new List<OpportunityLineItem>(); oliPickerList = new List<OpportunityLineItem>(); pbeListActive = new List<PricebookEntry>(); pbeCalculableSupportProductMap = new Map<Id,Decimal>(); pbeProductCodeMap = new Map<Id,String>(); pbeProductNameMap = new Map<Id,String>(); refreshData(); } /* STATIC METHODS */ /* Return set of Product Code values under 'CoreBlox' category in picker filter */ public static Set<String> getCoreBloxProductCodes(){ return COREBLOX_PRODUCT_CODES; } /** * Method returns a list of Product Use Case values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUseCaseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Use_Case__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Capability values as select options. * * @return a list of notes as select options */ public List<SelectOption> getCapabilityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Capability__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product License values as select options. * * @return a list of notes as select options */ public List<SelectOption> getLicenseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.License__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Up_to_Quantity values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUpToQuantityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Up_to_Quantity__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /* CLASS METHODS */ /* Add new product line items to Opportunity */ public void addProducts() { // Declare method variables PricebookEntry pbe; // Prepare selected items for insertion for (OpportunityLineItem oli : oliPickerList) { if (oli.Selected__c) { // Reset record-level variables pbe = pbeDetailsMapActive.get(oli.PricebookEntryId); // Set "Discount" to default value of 0 unless list price is 0 (in which case no discount could be applied) // Since record has not yet been inserted, cannot leverage formula field and must use map instead if (pbeDetailsMapActive.get(oli.PricebookEntryId).UnitPrice != 0 && oli.Discount__c == null) { oli.Discount__c = 0; } oli.Selected__c = FALSE; // Perform additional processing if (pbe.Product2.Calculate_Support_Pricing__c == 0) { // Set "Full Description" oli.Full_Description__c = ''; if (pbe.Product2.Price_Book_Group__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Group__c; } if (pbe.Product2.Price_Book_Type__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Type__c; } if (pbe.Product2.Price_Book_Environment__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Environment__c; } if (pbe.Product2.Price_Book_License__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_License__c; } if (pbe.Product2.Price_Book_Service__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Service__c; } if (pbe.Product2.Price_Book_Term__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Term__c; } if (pbe.Product2.Price_Book_Detailed_Description__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Detailed_Description__c; } // Set various fields related to the "Choices" field if (oli.Choices__c == 'CIC') { oli.Cloud_Identity_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'CK') { oli.Commercial_Integration_Kit__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'SC') { oli.SaaS_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'TT') { oli.Commercial_Translators__c = oli.Connector_Choice__c; } } oliNewList.add(oli); } } // Insert new line items if (!oliNewList.isEmpty()) { try { // Insert new line items insert oliNewList; hideAddProductsPanel(); refreshData(); updateCalculatedSupportProducts(); } catch (DMLException e) { ApexPages.addMessages(e); } oliNewList.clear(); } } /* Redirect user to pricebook selection page if pricebook is not yet selected */ public PageReference displayAppropriatePage() { // Declare method variables PageReference pageRef = null; // Perform redirection as appropriate if (currentOpp.Pricebook2Id == null && currentOpp.OpportunityLineItems.isEmpty()) { pageRef = new PageReference( '/oppitm/choosepricebook.jsp?id=' + currentOpp.Id + '&cancelURL=' + currentOpp.Id + '&saveURL=/apex/Manage_Products?id=' + currentOpp.Id ); pageRef.setRedirect(true); } return pageRef; } /* Disable rendering of add products panel and refresh data */ public PageReference hideAddProductsPanel() { showAddProductsPanel = false; return null; } /* Update or delete existing products */ public void modifyRecord() { // Declare method variables OpportunityLineItem currentOli; Pricebookentry pbe; refreshAddProductsTableData(); // Instantiate method variables currentOli = oliDetailsMap.get(currentOliId); pbe = pbeDetailsMapAll.get(currentOli.PricebookEntryId); // Perform update or delete try { if (action == 'update') { update currentOli; } else if (action == 'delete') { delete currentOli; } refreshData(); if (pbe.Product2.Calculate_Support_Pricing__c == 0) { updateCalculatedSupportProducts(); } } catch (DMLException e) { ApexPages.addMessages(e); } } /* Respond to user clicking on "Filter by Product Code:" dropdown in add products table */ public void refreshAddProductsTableData() { // Declare method variables String choices; String oppCurrency = currentOpp.CurrencyISOCode; String productCodeRoot; String productFilterSearchString = productFilter + '%'; String queryStr; Id pricebookId = currentOpp.Pricebook2Id; // Reset relevant class collections oliPickerList.clear(); pbeListActive.clear(); pbeListAll.clear(); pbeCalculableSupportProductMap.clear(); pbeProductCodeMap.clear(); pbeProductNameMap.clear(); // Build query queryStr = 'SELECT '; queryStr += 'Id, '; queryStr += 'IsActive, '; queryStr += 'Name, '; queryStr += 'ProductCode, '; queryStr += 'Product2Id, '; queryStr += 'Product2.Calculate_Support_Pricing__c, '; queryStr += 'Product2.Default_Support_Percentage__c, '; queryStr += 'Product2.Description, '; queryStr += 'Product2.Price_Book_Detailed_Description__c, '; queryStr += 'Product2.Price_Book_Environment__c, '; queryStr += 'Product2.Price_Book_Group__c, '; queryStr += 'Product2.Price_Book_License__c, '; queryStr += 'Product2.Price_Book_Service__c, '; queryStr += 'Product2.Price_Book_Term__c, '; queryStr += 'Product2.Price_Book_Type__c, '; queryStr += 'Product2.ProductCode, '; queryStr += 'UnitPrice '; queryStr += 'FROM PricebookEntry '; queryStr += 'WHERE Pricebook2Id = :pricebookId '; queryStr += 'AND CurrencyISOCode = :oppCurrency '; if (productFilter != 'All') { if (productFilter == 'CoreBlox') { queryStr += 'AND ProductCode IN :COREBLOX_PRODUCT_CODES '; } else { queryStr += 'AND ProductCode LIKE :productFilterSearchString '; } } if (useCase != 'All'){ queryStr += 'AND Product2.Use_Case__c = :useCase '; } if (capability != 'All'){ queryStr += 'AND Product2.Capability__c = :capability '; } if (license != 'All'){ queryStr += 'AND Product2.License__c = :license '; } if (upToQuantity != 'All'){ queryStr += 'AND Product2.Up_to_Quantity__c = :upToQuantity '; } queryStr += 'ORDER BY Name '; // Retrieve records and refill collections pbeListAll.addAll((List<PricebookEntry>)Database.query(queryStr)); for (PricebookEntry pbe : pbeListAll) { pbeDetailsMapAll.put(pbe.Id,pbe); if (pbe.IsActive) { // Reset record-level variables choices = null; productCodeRoot = pbe.ProductCode.left(pbe.ProductCode.indexOf('-')); // Fill collections pbeListActive.add(pbe); pbeDetailsMapActive.put(pbe.Id,pbe); pbeCalculableSupportProductMap.put(pbe.Id,pbe.Product2.Calculate_Support_Pricing__c); pbeProductCodeMap.put(pbe.Id, pbe.ProductCode); pbeProductNameMap.put(pbe.Id, pbe.Name); //Determine "Choices" variable if (VALID_CHOICES_SET.contains(productCodeRoot)) { choices = productCodeRoot; } oliPickerList.add(new OpportunityLineItem( Choices__c = choices, OpportunityId = currentOpp.Id, PricebookEntryId = pbe.Id, Quantity = 1, // Default value Support__c = pbe.Product2.Default_Support_Percentage__c, UnitPrice = pbe.UnitPrice )); } } } /* Query data and update variables */ public void refreshData() { // Reset variables to default values productFilter = 'All'; showAddProductsPanel = false; // Refresh Opportunity data currentOpp = [ SELECT Id, Amount, CurrencyIsoCode, IsClosed, Name, Owner.Name, Pricebook2Id, StageName, ( SELECT Id, Choices__c, Connector_Choice__c, Discount__c, Full_Description__c, ListPrice, PricebookEntryId, PricebookEntry.Product2.Calculate_Support_Pricing__c, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, Selected__c, Support__c, Support_Basis__c, Term_End_Date__c, Term_Start_Date__c, TotalPrice, UnitPrice // "Sales Price" FROM OpportunityLineItems WHERE IsDeleted = FALSE ORDER BY SortOrder ) FROM Opportunity WHERE Id = :currentOpp.Id ]; // Clear collections oliExistingList.clear(); oliDetailsMap.clear(); // Refill collections oliExistingList.addAll(currentOpp.OpportunityLineItems); for (OpportunityLineItem oli : oliExistingList) { oliDetailsMap.put(oli.Id,oli); } } /* Enable rendering of add products panel */ public PageReference showAddProductsPanel() { refreshAddProductsTableData(); showAddProductsPanel = true; return null; } /* Evaluate all line items on the Opportunity that require support, sum their total price together, * and from there calculate the default pricing for any calculable support products (such as Support * Gold) on the Opp. */ private void updateCalculatedSupportProducts() { // Declare method variables Decimal supportBasis = 0; String supportDescription = ''; PricebookEntry pbe; List<OpportunityLineItem> oliList = new List<OpportunityLineItem>(); for (OpportunityLineItem oli : oliExistingList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Aggregate non-support line item data if (pbe.Product2.Calculate_Support_Pricing__c == 0) { if (pbe.Product2.Price_Book_License__c != null && pbe.Product2.Price_Book_License__c.toLowerCase().contains('perpetual') ) { supportBasis += oli.Quantity * oli.UnitPrice; if (supportDescription != '') { supportDescription += ', '; } supportDescription += pbe.Product2.ProductCode; } // Tag as a support line item } else { // pbe.Product2.Calculate_Support_Pricing__c != 0 // oliList.add(oli); } } if (!oliList.isEmpty()) { // Perform processing on support line items for (OpportunityLineItem oli : oliList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Set price and description oli.UnitPrice = supportBasis * oli.Support__c / 100; oli.Full_Description__c = supportDescription; oli.Support_Basis__c = supportBasis; } // Perform DML // update oliList; refreshData(); } } }
- RossG
- October 30, 2014
- Like
- 0
too many soql queries error
oliMgr = new OppLineItemManager(triggerList);
in the following trigger:
trigger OpportunityLineItemTrigger on OpportunityLineItem ( before insert, before update, before delete, after insert, after update, after delete ) { if (!RecursionControl.getSuppressionFlag(RecursionControl.SuppressionFlag.OPPORTUNITY_LINE_ITEM_TRIGGER)) { // Declare trigger variables DeletionValidator oliDeletionValidator; OppLineItemManager oliMgr; OpportunityLineItem oliOld; List<OpportunityLineItem> oliListForRenewedFromInfo = new List<OpportunityLineItem>(); List<OpportunityLineItem> triggerList; Set<Id> contractIdSet = new Set<Id>(); Set<Id> oppIdSet = new Set<Id>(); // Aggregate trigger list into single variable if (Trigger.isInsert || Trigger.isUpdate) { triggerList = Trigger.new; } else { // Trigger.isDelete triggerList = Trigger.old; } // Perform evaluation for (OpportunityLineItem oliNew : triggerList) { // Reset record-level variables oliOld = Trigger.isUpdate ? Trigger.oldMap.get(oliNew.Id) : null; if (Trigger.isBefore) { if ((Trigger.isInsert && oliNew.Renewed_From_Line_Item_Record_Id__c != null) || (Trigger.isUpdate && oliNew.Renewed_From_Line_Item_Record_Id__c != oliOld.Renewed_From_Line_Item_Record_Id__c) ) { oliListForRenewedFromInfo.add(oliNew); } } else { // Trigger.isAfter if (Trigger.isUpdate) { if (oliOld.Contract__c != oliNew.Contract__c || oliOld.Quantity != oliNew.Quantity) { if (oliNew.Contract__c != null) { contractIdSet.add(oliNew.Contract__c); } if (oliOld.Contract__c != null) { contractIdSet.add(oliOld.Contract__c); } } } else { // Trigger.isInsert || Trigger.isDelete if (oliNew.Contract__c != null) { contractIdSet.add(oliNew.Contract__c); } } } } // Perform processing oliMgr = new OppLineItemManager(triggerList); if (Trigger.isBefore) { if (Trigger.isInsert) { oliMgr.setContractField(); } oliMgr.setGeneralLineItemFields(); if (!oliListForRenewedFromInfo.isEmpty()) { OppLineItemManager.setRenewedFromProductCode(oliListForRenewedFromInfo); } if (Trigger.isDelete) { oliDeletionValidator = new DeletionValidator(triggerList,DeletionValidator.ValidationType.LINE_ITEM); oliDeletionValidator.validateDeletion(); } } else if (Trigger.isAfter) { oliMgr.setParentOppRollupFields(); } if (!contractIdSet.isEmpty()) { OppLineItemManager.setSKPFieldOnContract(contractIdSet); } /* Code from Apex Trigger "CeligoTrigger_OpportunityLineItem", which was deactivated * in order to be consolidated here */ //context check if(Trigger.size<0)return; if(Trigger.isBefore && Trigger.isInsert){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.BeforeInsert).doTrigger(); //context check }else if(Trigger.isAfter && Trigger.isInsert){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterInsert).doTrigger(); }else if(Trigger.isAfter && Trigger.isUpdate){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterUpdate).doTrigger(); }else if(Trigger.isAfter && Trigger.isDelete){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterDelete).doTrigger(); } } }
Anyone see how I can modify this trigger code to avoid that error? Nothing I try seems to be working. Thanks a lot
- RossG
- October 28, 2014
- Like
- 0
apex tests not completing and change sets stuck in pending status
I have a case open with them about this but wanted to see if anyone else is having a similar experience right now.
- RossG
- October 21, 2014
- Like
- 0
Google Custom Search Element Control API and Visualforce
Does anyone know why this won's save? Obviously I don't know anything about javascript in vf:
<apex:page > <html> <head> <title>my site</title> </head> <body> <div1></div1> <script> (function() { var cx = '011892776069086249599:duc4yrcsujq'; var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true; gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cx; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s); })(); </script> <div2></div2> </body> </html> </apex:page>
- RossG
- September 08, 2014
- Like
- 0
batch job to count related records
if the lookup field value changes on the child object, the parent object's tally field must be updated appropriately.
In other words, this is how it should work:
object x
object y
a lookup field on object y to object x called "z"
a number field "a" on object x
batch job runs once a day and populates the field in object x called "a" with the the number of records in object y where object y's field "z" = x
here's an exampel that might be easier to visualize:
youve got account x with a new custom field called "number of contacts"
you've got 3 contacts on account x
run the batch job and it updates account x field "number of contacts" with a value of "3"
great. that is correct.
Now, update 1 of those 3 contacts such that it NO LONGER has an account = x but rather the contact is moved to another account
run the batch job again
account x should now show, after the job runs, a value of "2" in the "number of contacts" field
Any ideas on how this batch job class code would work, I'd really appreciate it. I can't seem to get it to work.
Thanks guys
- RossG
- July 23, 2014
- Like
- 0
Too many soql queries error in trigger code
I've got a new bit of coe for my lead trigger. This should just push a custom object related to the lead, upon conversion, to the generated contact.
I'm hittinga too many soql queries on deployment and was wondering if anyone sees how I could optimize this bit of code to get around that. The code works fine in sandbox in testing but does throw this error when deploying to prod. Here's the
trigger leadTtrigger on Lead (before update) { if (Trigger.isBefore) { // BEGIN PUSH PingOne Log records to contact on lead convert // if(Trigger.isUpdate){ Set<Id> leadIds = new Set<Id>(); Map<Id,Id> LeadIdContactId = new Map<Id,Id>(); for (Integer i = 0; i < Trigger.new.size(); i++){ if (Trigger.new[i].IsConverted == true && Trigger.old[i].isConverted == false){ leadIds.add(Trigger.new[i].id); LeadIdContactId.put(Trigger.new[i].id,Trigger.new[i].ConvertedContactId); } } List< PingOne_Log__c > CustomObjectsToUpdate = new List< PingOne_Log__c >(); List< PingOne_Log__c > customObjectEntries = [select Contact__c, Lead__c from PingOne_Log__c where lead__c in :leadIds]; for (Lead lead : [select id,ConvertedContactId from Lead where id in: leadIds]) { for (PingOne_Log__c CustomObject : customObjectEntries) { if (CustomObject.Lead__c == lead.Id) { CustomObject.contact__c = LeadIdContactId.get(lead.id); CustomObjectsToUpdate.add(CustomObject); } } } if(CustomObjectsToUpdate.size()>0) update CustomObjectsToUpdate; } }
code:
- RossG
- June 19, 2014
- Like
- 0
dynamic dependent picklist issue
I've overridden the standard "New" button functionality on the Lead object using a visualforce page and custom controller.
The purpose of this override is to allow for a dynamic dependent picklist when creating a new lead. Specifically, the requirement is: when a user selects a value from the standard lead picklist field called "Lead Source"...then...show a second custom field picklist called "Lead Source Detail". The values that the user sees in this second picklist must only be the names of Campaigns in SFDC that have a value in their Type field equal to the value the user selected in the Lead Source field.
Here's an example.
User clicks "New" button on the lead tab to create a new lead in the ui.
User sees the Lead Source picklist field. Let's say it has values of A,B,C. User selects A.
The user should then have the option of selecting a value in a second picklist field called Lead Source Detail. The options the user should see are only the campaigns in SFDC that have a Type field value of "A". So for example, say there are 2 campaigns in SFDC with a Type field value of "A". These would therefore be the only 2 selectable options in the Lead Source Detail field for the user.
The following code works for setting up a couple of dependent picklists on a lead New override screen, but, it's not quite there. I'm not sure how to modify it to get what I want above.
If you create a couple custom objects Category__c, Feature__c, and put a picklist field on Lead object called "Category__c", and put in the following 2 classes and VF page, and use the vf page to override the New button on Lead object, you'll see where I am. This all works to override the lead new button with a couple dyamic dependent picklists, but I need to modify this code so that, basically, the dependent picklist fields are:
1. the controlling field should be the lead.leadsource field and
2. the dependent picklist field should display a list of campaigns where the campaign type = the lead source value selected in option 1
the vf page:
<apex:page standardController="Lead" extensions="LeadNew_ControllerExtension2" title="Lead Edit" tabStyle="Lead"> <apex:form id="form"> <apex:pageBlock title="Lead Edit"> <apex:pageBlockButtons > <apex:commandButton action="{!doSave}" value="Save" /> <apex:commandButton action="{!cancel}" value="Cancel" /> </apex:pageBlockButtons> <apex:pageBlockSection title="Lead Information"> <apex:pageBlockSectionItem > <apex:outputlabel value="First Name"></apex:outputlabel> <apex:inputfield value="{!Lead.FirstName}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputlabel value="Last Name"></apex:outputlabel> <apex:inputfield value="{!Lead.LastName}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputlabel value="Company"></apex:outputlabel> <apex:inputfield value="{!Lead.Company}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputlabel value="Email"></apex:outputlabel> <apex:inputfield value="{!Lead.Email}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel for="productList" value="{!$ObjectType.Lead.fields.Product__c.label}" /> <apex:actionRegion > <apex:selectList value="{!product}" title="Product" size="1" id="products"> <apex:selectOptions value="{!productList}" /> <apex:actionSupport event="onchange" rerender="versions" /> </apex:selectList> </apex:actionRegion> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel for="versions" value="{!$ObjectType.Lead.fields.Version__c.label}" /> <apex:actionRegion > <apex:selectList value="{!version}" title="Version" size="1" id="versions"> <apex:selectOptions value="{!versionList}" /> </apex:selectList> </apex:actionRegion> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>the controller:
global with sharing class LeadNew_ControllerExtension2 { private final Id recordId; private final Lead record; private final ApexPages.StandardController controller; public LeadNew_ControllerExtension2(ApexPages.StandardController stdController) { this.controller = stdController; this.recordId = this.controller.getId(); this.record = [ select Id, ProductText__c,Product__c,Version__c,Product__r.Name,LeadSource,Lead_Source_Detail_Text__c, LastName,Email,Company, VersionText__c from Lead WHERE Product__c = null // where Id = :this.recordId limit 1 ]; } public List<SelectOption> getProductList() { List<SelectOption> products = new List<SelectOption>(); products.add(new SelectOption('', '--None--')); for (Product__c p: ProductUtils2.getAllProducts()) { products.add(new SelectOption(p.Id, p.Name)); } return products; } public Id getProduct() { return this.record.Product__c; } public void setProduct(Id productId) { this.record.Product__c = productId; } public List<SelectOption> getVersionList() { List<SelectOption> versions = new List<SelectOption>(); versions.add(new SelectOption('', '--None--')); if (record.Product__c != null) { for (Version__c v: ProductUtils2.getAllVersions(getProduct())) { versions.add(new SelectOption(v.Id, v.Name)); } } return versions; } public Id getVersion() { return this.record.Version__c; } public void setVersion(Id versionId) { this.record.Version__c= versionId; } public PageReference doSave() { Lead c = (Lead) controller.getRecord(); c.Product__c = this.record.Product__c; c.Lead_Source_Detail_Text__c = this.record.Version__c; upsert c; return new PageReference('/'+c.Id); } }
util class used in the controller:
public with sharing class ProductUtils2 { static public List<Product__c> getAllProducts(Boolean includeEOL) { return [ select Name from Product__c order by Name ]; } public static List<Product__c> getAllProducts() { return getAllProducts(false); } public static List<Version__c> getAllVersions(Id productId, Boolean test) { return [ select Name, Product__c from Version__c WHERE Product__c =: productId order by Name ]; } public static List<Version__c> getAllVersions(Id productId) { return getAllVersions(productId, false); } }
- RossG
- May 23, 2014
- Like
- 0
test class for sendEmail trigger
trigger DocusignStatusTrigger on dsfs__DocuSign_Status__c (after update) { for(dsfs__DocuSign_Status__c ds : Trigger.new){ if(ds.dsfs__Envelope_Status__c == 'Completed'){ Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); String[] toAddresses = new String[]{'rosstesta4@gmail.com','rossgilb@gmail.com','rosstesta3@gmail.com'}; mail.setToAddresses(toAddresses); mail.setReplyTo('rgilbert@pingidentity.com'); mail.setSenderDisplayName('Ping Identity'); mail.setSubject('A Ping Identity Sales Order has just been signed'); mail.setBccSender(false); mail.setUseSignature(false); mail.setPlainTextBody('A Ping Identity Sales Order for '+ ds.Account_Name__c +' has just been signed. You may view the signed document attached to this email, or view it as a PDF attachment in Salesforce, here: https://cs14.salesforce.com/' + ds.Id+'. The opportunity record for this envelope can be viewed here: https://cs14.salesforce.com/'+ ds.dsfs__Opportunity__c); mail.setTargetObjectId(ds.OwnerId); mail.saveAsActivity = false; List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>(); for (Attachment a : [select Name, Body, BodyLength from Attachment where ParentId = :ds.Id]){ Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment(); efa.setFileName(a.Name); efa.setBody(a.Body); fileAttachments.add(efa); } mail.setFileAttachments(fileAttachments); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } } }
- RossG
- May 19, 2014
- Like
- 0
Is it possible to programmatically add a new record to a custom object when a picklist value is added to a picklist field on another object?
- RossG
- May 14, 2014
- Like
- 0
How to bind a dynamic picklist value to an actual field
In other words let's say I've got a visualforce page that overrides the Lead edit page. This vf page has a couple dynamic picklists on it. On selecting values in those dynamic picklists, the user would click save, and the selected values would be mapped to actual fields on the Lead object. Not sure how to do this.
Here's a simple vf page that could override the lead edit button, along with it's custom controller. It seems to work, except for actually saving the dynamic picklist selections to the database.
Any help is appreciated
vf page: <apex:page standardController="Lead" extensions="DependentObjects" id="UseCaseDisplay" label="FeatureCategoryReport"> <apex:form > <apex:pageBlock title="New Lead" mode="edit"> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel"/> </apex:pageBlockButtons> <apex:pageBlockSection id="section1" title="Lead Information" columns="2" collapsible="true" ondblclick="toggleInputFieldsSales();"> <apex:inputField value="{!lead.LastName}"/> <apex:inputField value="{!lead.Email}"/> <apex:inputField value="{!lead.Company}"/> <apex:inputField value="{!lead.LeadSource}"/> <apex:inputField value="{!lead.Lead_Source_Detail__c}" /> </apex:pageBlockSection> <apex:pageblocksection > <table border="0" width="923px;"> <tr> <td align = "right"> <apex:outputLabel style="font-weight:bold;font-size:11px;" value="Lead Source" for="category"/> </td> <td> <apex:selectList style="align:right;" value="{!category}" size="1" id="category"> <apex:selectOptions value="{!categories}"/> <apex:actionSupport event="onchange" rerender="features"/> </apex:selectList> </td> </tr> <tr> <td align = "right"> <apex:outputLabel style="font-weight:bold;font-size:11px;" value="Lead Source Detail" for="features"/> </td> <td> <apex:selectList value="{!feature}" size="1" id="features" disabled="{!ISNULL(category)}"> <apex:selectOptions value="{!features}"/> </apex:selectList> </td> </tr> </table> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page> controller: public class DependentObjects { private final Lead acct; // The extension constructor initializes the private member // variable acct by using the getRecord method from the standard // controller. public DependentObjects(ApexPages.StandardController stdController) { this.acct = (Lead)stdController.getRecord(); } public String selectedAccName {get; set;} public DependentObjects() { selectedAccName = ''; } return page; } /* String value for the category */ String category; /* String value for the feature */ String feature; /* Getter for the category value */ public String getCategory() { return this.category; } /* Setter for the category value */ public void setCategory(String s) { this.category = s; } /* Getter for the feature value */ public String getFeature() { return this.feature; } /* Setter for the feature value */ public void setFeature(String s) { this.feature = s; } /* Getter which dynamically generates the categories from the Feature_Category__c object. */ public List<SelectOption> getCategories() { //List<SelectOption> optionList = new List<SelectOption>(); /* Add a null option to force the user to make a selection. */ // options.add(new SelectOption('','- None -')); /* Loop through the Lead records creating a selectOption for each result with the record ID as the value and the name as the label displayed in the selectList */ Set<String> uniqueCustomObjectSet = new Set<String>(); List<SelectOption> options = new List<SelectOption>(); options.add(new SelectOption('','- None -')); for(LeadSourceHidden__c sl:[Select LeadSourceHidden__c,Name From LeadSourceHidden__c WHERE LeadSourceHidden__c != null ORDER BY LeadSourceHidden__c DESC ]) { uniqueCustomObjectSet.add(sl.LeadSourceHidden__c); } List<String> uniqueCustomObjectList = new List<String>(uniqueCustomObjectSet); for(integer i=0; i<uniqueCustomObjectList.size(); i++){ options.add(new SelectOption(uniqueCustomObjectList[i],uniqueCustomObjectList[i])); } //options.add(new SelectOption('test','test')); return options; } /* Getter which generates the options for the features selectList based on the current value of the selected category. If there is no value selected then only the null option should be returned. */ public List<SelectOption> getFeatures() { List<SelectOption> optionList = new List<SelectOption>(); /* Add a null option to force the user to make a selection. */ optionList.add(new SelectOption('', '- None -')); /* If a category has been selected then query for the related values */ if(category != NULL) { /* Loop over the related campaign records for the given lead source creating a selectOption with the value being the feature record ID and the label is the name of the lead source. */ for (Campaign f : [select Name,Type from Campaign f where f.Type =: category LIMIT 40000 ]){ optionList.add(new SelectOption(f.Id,f.Name)); } } return optionList; } }
- RossG
- May 12, 2014
- Like
- 0
Retrieve userId without SOQL in apex class
I am having a problem that should be really easy to solve. It's easy to retrieve a user id in a trigger or class using soql. But I am hitting a soql 101 limit error and thus need to have my code run some of one of my trigger when a specific user creates a record. I can also do this by simply hardcoding the user's id in the trigger, but I don't want to do that.
Basically the algorithm is: trigger on object x updates a few fields on a record after it is interted, but only when user "a" creates the record. The trigger should simply call a class that updates some fields on that newly inserted record by that specific user. The trick is, in the trigger, specify the user who should be allowed to call that class without hardcoding the user's ID.
Basically what I need is a utiluty class I can call that returns the userId of the current user based on his/her alias or username. Any ideas?
- RossG
- February 25, 2014
- Like
- 0
getting partner data on an opp
So sf has a standard opportunity object and a standard partner object whereby an opp can have 1 or more partners (opportunity partners).
Yet, there appears to be no way through formulas, roll up fields, triggers, workflow....zero options...for capturing any info or data...at all...on an opportunity with regard to that opps partners. In other words, let's say I want to know even the most basic thing:
does this opp have a partner on it?
I can't even create a field that populates that data by looking at the opportunity partners on the opp.
It appears the only way to do this is with a batch or scheduled batch job which is ridiculous.
Has anyone else had this problem? Is there any way to summarize any partner info on an opp? At all? Thanks
- RossG
- October 28, 2013
- Like
- 0
help with custom button
Hi,
I've got a url custom detail page button that i need to add some conditional logic to. Unfortunately the output I need isn't working properly now, because the out =put is text, but I need to use some merge fields.
Here's my button. It compiles, but it doesn't work. Reason it does not work is something with the syntax in the output when the IF statement is true.
http://{! IF( ISPICKVAL (Opportunity.StageName, "Won"), "www.appextremes.com/apps/Conga/PointMerge.aspx?sessionId={!API.Session_ID}&serverUrl={!API.Partner_Server_URL_80}&id={!Opportunity.Id}", "www.google.com" ) }
As you can see the formula just spits out a text string there, but I've got merge fields within that text string which won't work.
Just hoping someone has dealt with this before. Any ideas?
Thanks a lot
- RossG
- October 22, 2013
- Like
- 0
App to calculate Partner Referral Fees?
Has anyone used any apps off the appexchange or calculating and managing partner referral fees? We could do this ourselves with apex but I wanted to see if there's an app out there already for this.
Basically what the app would do is calculate how much $ should be paid to a partner, for a given opportunity, based on terms in that partner's contract and other variables (for example, which product or products were sold on the opp). The app would look at those criteria and caculate the partner referral fee for the opp.
Please let me be clear that I'm not looking for a custom solution here. I just want to know if there's an app for this already.
Thanks a lot,
Ross
- RossG
- October 07, 2013
- Like
- 0
Test class for Messaging class
Hey guys-
I've got a simple messaging class that works great, but I need a solid test class for it.
All this is is a class that's called from a javascript custom button that is on the page layout of a custom object record. When someone click the button, it calls this class, and an email is sent out to the email you can see in the class (I've changed it for anonymity here to 'test@test.com')
global class CIFEmails { WebService static void SendEmailNotification(string id, string accountName) { //create a mail object to send a single email. Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); //set the email properties mail.setToAddresses(new string[] {'test@test.com'}); mail.setSenderDisplayName('Ping Salesforce'); mail.setSubject('A CIF Has Just Been Submitted to Contracts & Licensing for: ' + accountName ); mail.setHtmlBody('A Customer Information Form has just been Submitted to Contracts & Licensing.'+ 'To access the CIF, please go to the record in Salesforce, here: '+ 'https://cs15.salesforce.com/' + id); //send the email Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail } ); } }
So, I need no test class for my javascript button. But I do need a test class for the messaging class above.
Problem I see is the SF developer documentation is lacking on how to test emails sent via apex.
Anyone have any code I could take a look at that is a GOOD test class for this class? Doesn't have to be bulkified in this case since the class is only ever called from a custom button.
Thanks a lot for any help anyone can provide
- RossG
- September 04, 2013
- Like
- 0
too many soql queries error
if(Trigger.isInsert || Trigger.isUpdate){ if(HelperClass.firstRun2){ HelperClass.firstRun2=false; for(Lead l1: trigger.new){ if((UserInfo.getUserId() == Label.MarketoIntegrationUser || UserInfo.getUserId() == Label.WebsiteIntegrationUser) && (l1.RecordTypeId == leadRecordTypeId) && (l1.Country == 'United States' || l1.Country == 'United States of America' || l1.Country == 'USA' || l1.Country == 'U.S.' || l1.Country == 'U.S.A' ) ){ Set<String> postalCodes = new Set<String>(); for( Lead l : trigger.new ) { if(l.PostalCode != null && l.PostalCode.length() >=5) try{ String zipStringx = l.PostalCode.substring(0,5); postalCodes.add( zipStringx ); // postalCodes.add( l.PostalCode ); } catch(DMLException e){ ApexPages.addMessages(e); Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {'sfdc-admins@pingidentity.com'}; mail.setToAddresses(toAddresses); mail.setReplyTo('sfdc-admins@pingidentity.com'); mail.setSenderDisplayName('Apex error message'); mail.setSubject('Error from Org : ' + UserInfo.getOrganizationName()); mail.setPlainTextBody(e.getMessage()); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } } Map<String, Zip_State_Table__c > validZips = new Map<String, Zip_State_Table__c >(); for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); } for( Lead l : trigger.new ) { if( l.PostalCode != null && l.PostalCode.length() >=5 ) { if( validZips.containsKey(l.PostalCode.substring(0,5)) ) { l.State = validZips.get(l.PostalCode.substring(0,5)).Name; l.RegionTerritoryHidden__c = validZips.get(l.PostalCode.substring(0,5)).Territory__c; } else {} } } } } } }
I know the error in the above code is with this part of the code:
for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); }
I'm unable to re-write that code to avoid the error. Does anyone see how I can re-write that code with the soql query for loop to avoid the too many soql queries error? Thanks
- RossG
- December 03, 2014
- Like
- 0
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: LeadTrigger: execution of BeforeUpdate caused by: System.StringException: Ending position out of bounds: 5 Trigger.LeadTrigger: line 58, column 1\n
The offending line is in the code below where it says:
String zipStringx = l.PostalCode.substring(0,5);
Does anyone know how I could tweak this code to prevent that error? Thanks. Here's the full code for hte lead trigger where this occurs:
/*Begin Processing United States leads*/ if(Trigger.isInsert || Trigger.isUpdate){ if(HelperClass.firstRun2){ HelperClass.firstRun2=false; for(Lead l1: trigger.new){ if((UserInfo.getUserId() == Label.MarketoIntegrationUser || UserInfo.getUserId() == Label.WebsiteIntegrationUser) && (l1.RecordTypeId == leadRecordTypeId) && (l1.Country == 'United States' || l1.Country == 'United States of America' || l1.Country == 'USA' || l1.Country == 'U.S.' || l1.Country == 'U.S.A' ) ){ Set<String> postalCodes = new Set<String>(); for( Lead l : trigger.new ) { if(l.PostalCode != null){ String zipStringx = l.PostalCode.substring(0,5); postalCodes.add( zipStringx ); // postalCodes.add( l.PostalCode ); } else{} } Map<String, Zip_State_Table__c > validZips = new Map<String, Zip_State_Table__c >(); for( Zip_State_Table__c obj : [SELECT Id, Name, ZipCode__c, Territory__c FROM Zip_State_Table__c WHERE ZipCode__c IN :postalCodes] ) { validZips.put( obj.ZipCode__c, obj ); } for( Lead l : trigger.new ) { if( l.PostalCode != null ) { if( validZips.containsKey(l.PostalCode.substring(0,5)) ) { l.State = validZips.get(l.PostalCode.substring(0,5)).Name; l.RegionTerritoryHidden__c = validZips.get(l.PostalCode.substring(0,5)).Territory__c; } else {} } } } } } }
- RossG
- November 10, 2014
- Like
- 0
attempt to de-reference a null object error
This is a visualforce page with custom controller that is basically a custom product picker on opportunity object. The error I get when trying to add a product to the opp is:
Attempt to de-reference a null object
Error is in expression '{!modifyRecord}' in page manage_products: Class.ManageProductsController.modifyRecord: line 324, column 1
Does anyone see anything in this code below that could be causing the error?
public class ManageProductsController { /* Controller for "Manage Products" Visualforce Page, aka the "product picker" */ // Declare static variables private static final Map<String,String> PRODUCT_FILTER_VALUES_MAP; private static final Set<String> COREBLOX_PRODUCT_CODES = new Set<String>{'CBWK-H-PUL','PE-CS-CBWS'}; private static final Set<String> VALID_CHOICES_SET = new Set<String>{ 'CIC','CK','SC','TT' }; private static final Set<Id> ADMIN_PROFILE_ID_SET; // Which profiles can use product picker to edit won Opps private static final string PICKLIST_DEFAULT = 'All'; //defailt picklist value // Declare public class variables public Boolean editAfterClosed { get { return (editAfterClosed == null) ? false : editAfterClosed; } set; } public Boolean showAddProductsPanel { get { return (showAddProductsPanel == null) ? false : showAddProductsPanel; } set; } public String action { get; set; } public String productFilter { get; set; } public String useCase { get; set; } public String capability { get; set; } public String license { get; set; } public String upToQuantity { get; set; } public Id currentOliId { get; set; } public Opportunity currentOpp { get; set; } public List<OpportunityLineItem> oliExistingList { get; set; } public List<OpportunityLineItem> oliPickerList { get; set; } public List<PricebookEntry> pbeListActive { get; set; } public List<SelectOption> productFilterValues { get; set; } public Map<Id,Decimal> pbeCalculableSupportProductMap { get; set; } public Map<Id,String> pbeProductCodeMap { get; set; } public Map<Id,String> pbeProductNameMap { get; set; } public Map<Id,OpportunityLineItem> oliDetailsMap { get; set; } // Declare private class variables private ApexPages.StandardController stdController; private List<OpportunityLineItem> oliNewList = new List<OpportunityLineItem>(); private List<PricebookEntry> pbeListAll = new List<PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapAll = new Map<Id,PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapActive = new Map<Id,PricebookEntry>(); // Instantiate static variables static { ADMIN_PROFILE_ID_SET = new Set<Id>{ '00e40000000rTp1', // Custom Contract Admin '00e30000000bzB3' // System Administrator }; PRODUCT_FILTER_VALUES_MAP = new Map<String,String>{ 'All' => 'All', 'Bundles' => 'CB', 'Cloud Identity Connector' => 'CIC', 'Commercial Integration Kit' => 'CK', 'Connection Based' => 'CONN', 'CoreBlox' => 'CoreBlox', 'Discount' => 'Cust', 'ELA' => 'ELA', 'Endpoint' => 'EP', 'Oauth Add-on' => 'OAA', 'Oauth Standalone' => 'OAS', 'PingAccess' => 'PA', 'PingConnect' => 'PC', 'PingEnable Consulting' => 'PE', 'PingFed Server' => 'PFS', 'PingOne' => 'PO', 'PingEnable Training' => 'PT', 'Saas Program Bundle' => 'Saas', 'SaaS Connector' => 'SC', 'STS Add-on' => 'SSA', 'STS Standalone' => 'SSS', 'Support' => 'SUP', 'Token Translator' => 'TT', 'WAM Integration Kit' => 'WMIK', 'WAM Token Translator' => 'WMTT' }; } /* Constructor */ public ManageProductsController(ApexPages.StandardController stdController) { // Instantiate class variables this.stdController = stdController; currentOpp = (Opportunity)stdController.getRecord(); editAfterClosed = false; // Default value if (ADMIN_PROFILE_ID_SET.contains(UserInfo.getProfileId())) { editAfterClosed = true; } productFilterValues = new List<SelectOption>(); for (String s : PRODUCT_FILTER_VALUES_MAP.keySet()) { productFilterValues.add(new SelectOption(PRODUCT_FILTER_VALUES_MAP.get(s),s)); } productFilterValues.sort(); oliDetailsMap = new Map<Id,OpportunityLineItem>(); oliExistingList = new List<OpportunityLineItem>(); oliPickerList = new List<OpportunityLineItem>(); pbeListActive = new List<PricebookEntry>(); pbeCalculableSupportProductMap = new Map<Id,Decimal>(); pbeProductCodeMap = new Map<Id,String>(); pbeProductNameMap = new Map<Id,String>(); refreshData(); } /* STATIC METHODS */ /* Return set of Product Code values under 'CoreBlox' category in picker filter */ public static Set<String> getCoreBloxProductCodes(){ return COREBLOX_PRODUCT_CODES; } /** * Method returns a list of Product Use Case values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUseCaseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Use_Case__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Capability values as select options. * * @return a list of notes as select options */ public List<SelectOption> getCapabilityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Capability__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product License values as select options. * * @return a list of notes as select options */ public List<SelectOption> getLicenseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.License__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Up_to_Quantity values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUpToQuantityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Up_to_Quantity__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /* CLASS METHODS */ /* Add new product line items to Opportunity */ public void addProducts() { // Declare method variables PricebookEntry pbe; // Prepare selected items for insertion for (OpportunityLineItem oli : oliPickerList) { if (oli.Selected__c) { // Reset record-level variables pbe = pbeDetailsMapActive.get(oli.PricebookEntryId); // Set "Discount" to default value of 0 unless list price is 0 (in which case no discount could be applied) // Since record has not yet been inserted, cannot leverage formula field and must use map instead if (pbeDetailsMapActive.get(oli.PricebookEntryId).UnitPrice != 0 && oli.Discount__c == null) { oli.Discount__c = 0; } oli.Selected__c = FALSE; // Perform additional processing if (pbe.Product2.Calculate_Support_Pricing__c == 0) { // Set "Full Description" oli.Full_Description__c = ''; if (pbe.Product2.Price_Book_Group__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Group__c; } if (pbe.Product2.Price_Book_Type__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Type__c; } if (pbe.Product2.Price_Book_Environment__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Environment__c; } if (pbe.Product2.Price_Book_License__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_License__c; } if (pbe.Product2.Price_Book_Service__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Service__c; } if (pbe.Product2.Price_Book_Term__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Term__c; } if (pbe.Product2.Price_Book_Detailed_Description__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Detailed_Description__c; } // Set various fields related to the "Choices" field if (oli.Choices__c == 'CIC') { oli.Cloud_Identity_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'CK') { oli.Commercial_Integration_Kit__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'SC') { oli.SaaS_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'TT') { oli.Commercial_Translators__c = oli.Connector_Choice__c; } } oliNewList.add(oli); } } // Insert new line items if (!oliNewList.isEmpty()) { try { // Insert new line items insert oliNewList; hideAddProductsPanel(); refreshData(); updateCalculatedSupportProducts(); } catch (DMLException e) { ApexPages.addMessages(e); } oliNewList.clear(); } } /* Redirect user to pricebook selection page if pricebook is not yet selected */ public PageReference displayAppropriatePage() { // Declare method variables PageReference pageRef = null; // Perform redirection as appropriate if (currentOpp.Pricebook2Id == null && currentOpp.OpportunityLineItems.isEmpty()) { pageRef = new PageReference( '/oppitm/choosepricebook.jsp?id=' + currentOpp.Id + '&cancelURL=' + currentOpp.Id + '&saveURL=/apex/Manage_Products?id=' + currentOpp.Id ); pageRef.setRedirect(true); } return pageRef; } /* Disable rendering of add products panel and refresh data */ public PageReference hideAddProductsPanel() { showAddProductsPanel = false; return null; } /* Update or delete existing products */ public void modifyRecord() { // Declare method variables OpportunityLineItem currentOli; Pricebookentry pbe; refreshAddProductsTableData(); // Instantiate method variables currentOli = oliDetailsMap.get(currentOliId); pbe = pbeDetailsMapAll.get(currentOli.PricebookEntryId); // Perform update or delete try { if (action == 'update') { update currentOli; } else if (action == 'delete') { delete currentOli; } refreshData(); if (pbe.Product2.Calculate_Support_Pricing__c == 0) { updateCalculatedSupportProducts(); } } catch (DMLException e) { ApexPages.addMessages(e); } } /* Respond to user clicking on "Filter by Product Code:" dropdown in add products table */ public void refreshAddProductsTableData() { // Declare method variables String choices; String oppCurrency = currentOpp.CurrencyISOCode; String productCodeRoot; String productFilterSearchString = productFilter + '%'; String queryStr; Id pricebookId = currentOpp.Pricebook2Id; // Reset relevant class collections oliPickerList.clear(); pbeListActive.clear(); pbeListAll.clear(); pbeCalculableSupportProductMap.clear(); pbeProductCodeMap.clear(); pbeProductNameMap.clear(); // Build query queryStr = 'SELECT '; queryStr += 'Id, '; queryStr += 'IsActive, '; queryStr += 'Name, '; queryStr += 'ProductCode, '; queryStr += 'Product2Id, '; queryStr += 'Product2.Calculate_Support_Pricing__c, '; queryStr += 'Product2.Default_Support_Percentage__c, '; queryStr += 'Product2.Description, '; queryStr += 'Product2.Price_Book_Detailed_Description__c, '; queryStr += 'Product2.Price_Book_Environment__c, '; queryStr += 'Product2.Price_Book_Group__c, '; queryStr += 'Product2.Price_Book_License__c, '; queryStr += 'Product2.Price_Book_Service__c, '; queryStr += 'Product2.Price_Book_Term__c, '; queryStr += 'Product2.Price_Book_Type__c, '; queryStr += 'Product2.ProductCode, '; queryStr += 'UnitPrice '; queryStr += 'FROM PricebookEntry '; queryStr += 'WHERE Pricebook2Id = :pricebookId '; queryStr += 'AND CurrencyISOCode = :oppCurrency '; if (productFilter != 'All') { if (productFilter == 'CoreBlox') { queryStr += 'AND ProductCode IN :COREBLOX_PRODUCT_CODES '; } else { queryStr += 'AND ProductCode LIKE :productFilterSearchString '; } } if (useCase != 'All'){ queryStr += 'AND Product2.Use_Case__c = :useCase '; } if (capability != 'All'){ queryStr += 'AND Product2.Capability__c = :capability '; } if (license != 'All'){ queryStr += 'AND Product2.License__c = :license '; } if (upToQuantity != 'All'){ queryStr += 'AND Product2.Up_to_Quantity__c = :upToQuantity '; } queryStr += 'ORDER BY Name '; // Retrieve records and refill collections pbeListAll.addAll((List<PricebookEntry>)Database.query(queryStr)); for (PricebookEntry pbe : pbeListAll) { pbeDetailsMapAll.put(pbe.Id,pbe); if (pbe.IsActive) { // Reset record-level variables choices = null; productCodeRoot = pbe.ProductCode.left(pbe.ProductCode.indexOf('-')); // Fill collections pbeListActive.add(pbe); pbeDetailsMapActive.put(pbe.Id,pbe); pbeCalculableSupportProductMap.put(pbe.Id,pbe.Product2.Calculate_Support_Pricing__c); pbeProductCodeMap.put(pbe.Id, pbe.ProductCode); pbeProductNameMap.put(pbe.Id, pbe.Name); //Determine "Choices" variable if (VALID_CHOICES_SET.contains(productCodeRoot)) { choices = productCodeRoot; } oliPickerList.add(new OpportunityLineItem( Choices__c = choices, OpportunityId = currentOpp.Id, PricebookEntryId = pbe.Id, Quantity = 1, // Default value Support__c = pbe.Product2.Default_Support_Percentage__c, UnitPrice = pbe.UnitPrice )); } } } /* Query data and update variables */ public void refreshData() { // Reset variables to default values productFilter = 'All'; showAddProductsPanel = false; // Refresh Opportunity data currentOpp = [ SELECT Id, Amount, CurrencyIsoCode, IsClosed, Name, Owner.Name, Pricebook2Id, StageName, ( SELECT Id, Choices__c, Connector_Choice__c, Discount__c, Full_Description__c, ListPrice, PricebookEntryId, PricebookEntry.Product2.Calculate_Support_Pricing__c, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, Selected__c, Support__c, Support_Basis__c, Term_End_Date__c, Term_Start_Date__c, TotalPrice, UnitPrice // "Sales Price" FROM OpportunityLineItems WHERE IsDeleted = FALSE ORDER BY SortOrder ) FROM Opportunity WHERE Id = :currentOpp.Id ]; // Clear collections oliExistingList.clear(); oliDetailsMap.clear(); // Refill collections oliExistingList.addAll(currentOpp.OpportunityLineItems); for (OpportunityLineItem oli : oliExistingList) { oliDetailsMap.put(oli.Id,oli); } } /* Enable rendering of add products panel */ public PageReference showAddProductsPanel() { refreshAddProductsTableData(); showAddProductsPanel = true; return null; } /* Evaluate all line items on the Opportunity that require support, sum their total price together, * and from there calculate the default pricing for any calculable support products (such as Support * Gold) on the Opp. */ private void updateCalculatedSupportProducts() { // Declare method variables Decimal supportBasis = 0; String supportDescription = ''; PricebookEntry pbe; List<OpportunityLineItem> oliList = new List<OpportunityLineItem>(); for (OpportunityLineItem oli : oliExistingList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Aggregate non-support line item data if (pbe.Product2.Calculate_Support_Pricing__c == 0) { if (pbe.Product2.Price_Book_License__c != null && pbe.Product2.Price_Book_License__c.toLowerCase().contains('perpetual') ) { supportBasis += oli.Quantity * oli.UnitPrice; if (supportDescription != '') { supportDescription += ', '; } supportDescription += pbe.Product2.ProductCode; } // Tag as a support line item } else { // pbe.Product2.Calculate_Support_Pricing__c != 0 // oliList.add(oli); } } if (!oliList.isEmpty()) { // Perform processing on support line items for (OpportunityLineItem oli : oliList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Set price and description oli.UnitPrice = supportBasis * oli.Support__c / 100; oli.Full_Description__c = supportDescription; oli.Support_Basis__c = supportBasis; } // Perform DML // update oliList; refreshData(); } } }
- RossG
- October 30, 2014
- Like
- 0
too many soql queries error
oliMgr = new OppLineItemManager(triggerList);
in the following trigger:
trigger OpportunityLineItemTrigger on OpportunityLineItem ( before insert, before update, before delete, after insert, after update, after delete ) { if (!RecursionControl.getSuppressionFlag(RecursionControl.SuppressionFlag.OPPORTUNITY_LINE_ITEM_TRIGGER)) { // Declare trigger variables DeletionValidator oliDeletionValidator; OppLineItemManager oliMgr; OpportunityLineItem oliOld; List<OpportunityLineItem> oliListForRenewedFromInfo = new List<OpportunityLineItem>(); List<OpportunityLineItem> triggerList; Set<Id> contractIdSet = new Set<Id>(); Set<Id> oppIdSet = new Set<Id>(); // Aggregate trigger list into single variable if (Trigger.isInsert || Trigger.isUpdate) { triggerList = Trigger.new; } else { // Trigger.isDelete triggerList = Trigger.old; } // Perform evaluation for (OpportunityLineItem oliNew : triggerList) { // Reset record-level variables oliOld = Trigger.isUpdate ? Trigger.oldMap.get(oliNew.Id) : null; if (Trigger.isBefore) { if ((Trigger.isInsert && oliNew.Renewed_From_Line_Item_Record_Id__c != null) || (Trigger.isUpdate && oliNew.Renewed_From_Line_Item_Record_Id__c != oliOld.Renewed_From_Line_Item_Record_Id__c) ) { oliListForRenewedFromInfo.add(oliNew); } } else { // Trigger.isAfter if (Trigger.isUpdate) { if (oliOld.Contract__c != oliNew.Contract__c || oliOld.Quantity != oliNew.Quantity) { if (oliNew.Contract__c != null) { contractIdSet.add(oliNew.Contract__c); } if (oliOld.Contract__c != null) { contractIdSet.add(oliOld.Contract__c); } } } else { // Trigger.isInsert || Trigger.isDelete if (oliNew.Contract__c != null) { contractIdSet.add(oliNew.Contract__c); } } } } // Perform processing oliMgr = new OppLineItemManager(triggerList); if (Trigger.isBefore) { if (Trigger.isInsert) { oliMgr.setContractField(); } oliMgr.setGeneralLineItemFields(); if (!oliListForRenewedFromInfo.isEmpty()) { OppLineItemManager.setRenewedFromProductCode(oliListForRenewedFromInfo); } if (Trigger.isDelete) { oliDeletionValidator = new DeletionValidator(triggerList,DeletionValidator.ValidationType.LINE_ITEM); oliDeletionValidator.validateDeletion(); } } else if (Trigger.isAfter) { oliMgr.setParentOppRollupFields(); } if (!contractIdSet.isEmpty()) { OppLineItemManager.setSKPFieldOnContract(contractIdSet); } /* Code from Apex Trigger "CeligoTrigger_OpportunityLineItem", which was deactivated * in order to be consolidated here */ //context check if(Trigger.size<0)return; if(Trigger.isBefore && Trigger.isInsert){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.BeforeInsert).doTrigger(); //context check }else if(Trigger.isAfter && Trigger.isInsert){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterInsert).doTrigger(); }else if(Trigger.isAfter && Trigger.isUpdate){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterUpdate).doTrigger(); }else if(Trigger.isAfter && Trigger.isDelete){ new CeligoTrigger_OpportunityLineItem(Trigger.new,Trigger.old, CeligoTrigger.TriggerType.AfterDelete).doTrigger(); } } }
Anyone see how I can modify this trigger code to avoid that error? Nothing I try seems to be working. Thanks a lot
- RossG
- October 28, 2014
- Like
- 0
batch job to count related records
if the lookup field value changes on the child object, the parent object's tally field must be updated appropriately.
In other words, this is how it should work:
object x
object y
a lookup field on object y to object x called "z"
a number field "a" on object x
batch job runs once a day and populates the field in object x called "a" with the the number of records in object y where object y's field "z" = x
here's an exampel that might be easier to visualize:
youve got account x with a new custom field called "number of contacts"
you've got 3 contacts on account x
run the batch job and it updates account x field "number of contacts" with a value of "3"
great. that is correct.
Now, update 1 of those 3 contacts such that it NO LONGER has an account = x but rather the contact is moved to another account
run the batch job again
account x should now show, after the job runs, a value of "2" in the "number of contacts" field
Any ideas on how this batch job class code would work, I'd really appreciate it. I can't seem to get it to work.
Thanks guys
- RossG
- July 23, 2014
- Like
- 0
Too many soql queries error in trigger code
I've got a new bit of coe for my lead trigger. This should just push a custom object related to the lead, upon conversion, to the generated contact.
I'm hittinga too many soql queries on deployment and was wondering if anyone sees how I could optimize this bit of code to get around that. The code works fine in sandbox in testing but does throw this error when deploying to prod. Here's the
trigger leadTtrigger on Lead (before update) { if (Trigger.isBefore) { // BEGIN PUSH PingOne Log records to contact on lead convert // if(Trigger.isUpdate){ Set<Id> leadIds = new Set<Id>(); Map<Id,Id> LeadIdContactId = new Map<Id,Id>(); for (Integer i = 0; i < Trigger.new.size(); i++){ if (Trigger.new[i].IsConverted == true && Trigger.old[i].isConverted == false){ leadIds.add(Trigger.new[i].id); LeadIdContactId.put(Trigger.new[i].id,Trigger.new[i].ConvertedContactId); } } List< PingOne_Log__c > CustomObjectsToUpdate = new List< PingOne_Log__c >(); List< PingOne_Log__c > customObjectEntries = [select Contact__c, Lead__c from PingOne_Log__c where lead__c in :leadIds]; for (Lead lead : [select id,ConvertedContactId from Lead where id in: leadIds]) { for (PingOne_Log__c CustomObject : customObjectEntries) { if (CustomObject.Lead__c == lead.Id) { CustomObject.contact__c = LeadIdContactId.get(lead.id); CustomObjectsToUpdate.add(CustomObject); } } } if(CustomObjectsToUpdate.size()>0) update CustomObjectsToUpdate; } }
code:
- RossG
- June 19, 2014
- Like
- 0
Is it possible to programmatically add a new record to a custom object when a picklist value is added to a picklist field on another object?
- RossG
- May 14, 2014
- Like
- 0
How to bind a dynamic picklist value to an actual field
In other words let's say I've got a visualforce page that overrides the Lead edit page. This vf page has a couple dynamic picklists on it. On selecting values in those dynamic picklists, the user would click save, and the selected values would be mapped to actual fields on the Lead object. Not sure how to do this.
Here's a simple vf page that could override the lead edit button, along with it's custom controller. It seems to work, except for actually saving the dynamic picklist selections to the database.
Any help is appreciated
vf page: <apex:page standardController="Lead" extensions="DependentObjects" id="UseCaseDisplay" label="FeatureCategoryReport"> <apex:form > <apex:pageBlock title="New Lead" mode="edit"> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel"/> </apex:pageBlockButtons> <apex:pageBlockSection id="section1" title="Lead Information" columns="2" collapsible="true" ondblclick="toggleInputFieldsSales();"> <apex:inputField value="{!lead.LastName}"/> <apex:inputField value="{!lead.Email}"/> <apex:inputField value="{!lead.Company}"/> <apex:inputField value="{!lead.LeadSource}"/> <apex:inputField value="{!lead.Lead_Source_Detail__c}" /> </apex:pageBlockSection> <apex:pageblocksection > <table border="0" width="923px;"> <tr> <td align = "right"> <apex:outputLabel style="font-weight:bold;font-size:11px;" value="Lead Source" for="category"/> </td> <td> <apex:selectList style="align:right;" value="{!category}" size="1" id="category"> <apex:selectOptions value="{!categories}"/> <apex:actionSupport event="onchange" rerender="features"/> </apex:selectList> </td> </tr> <tr> <td align = "right"> <apex:outputLabel style="font-weight:bold;font-size:11px;" value="Lead Source Detail" for="features"/> </td> <td> <apex:selectList value="{!feature}" size="1" id="features" disabled="{!ISNULL(category)}"> <apex:selectOptions value="{!features}"/> </apex:selectList> </td> </tr> </table> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page> controller: public class DependentObjects { private final Lead acct; // The extension constructor initializes the private member // variable acct by using the getRecord method from the standard // controller. public DependentObjects(ApexPages.StandardController stdController) { this.acct = (Lead)stdController.getRecord(); } public String selectedAccName {get; set;} public DependentObjects() { selectedAccName = ''; } return page; } /* String value for the category */ String category; /* String value for the feature */ String feature; /* Getter for the category value */ public String getCategory() { return this.category; } /* Setter for the category value */ public void setCategory(String s) { this.category = s; } /* Getter for the feature value */ public String getFeature() { return this.feature; } /* Setter for the feature value */ public void setFeature(String s) { this.feature = s; } /* Getter which dynamically generates the categories from the Feature_Category__c object. */ public List<SelectOption> getCategories() { //List<SelectOption> optionList = new List<SelectOption>(); /* Add a null option to force the user to make a selection. */ // options.add(new SelectOption('','- None -')); /* Loop through the Lead records creating a selectOption for each result with the record ID as the value and the name as the label displayed in the selectList */ Set<String> uniqueCustomObjectSet = new Set<String>(); List<SelectOption> options = new List<SelectOption>(); options.add(new SelectOption('','- None -')); for(LeadSourceHidden__c sl:[Select LeadSourceHidden__c,Name From LeadSourceHidden__c WHERE LeadSourceHidden__c != null ORDER BY LeadSourceHidden__c DESC ]) { uniqueCustomObjectSet.add(sl.LeadSourceHidden__c); } List<String> uniqueCustomObjectList = new List<String>(uniqueCustomObjectSet); for(integer i=0; i<uniqueCustomObjectList.size(); i++){ options.add(new SelectOption(uniqueCustomObjectList[i],uniqueCustomObjectList[i])); } //options.add(new SelectOption('test','test')); return options; } /* Getter which generates the options for the features selectList based on the current value of the selected category. If there is no value selected then only the null option should be returned. */ public List<SelectOption> getFeatures() { List<SelectOption> optionList = new List<SelectOption>(); /* Add a null option to force the user to make a selection. */ optionList.add(new SelectOption('', '- None -')); /* If a category has been selected then query for the related values */ if(category != NULL) { /* Loop over the related campaign records for the given lead source creating a selectOption with the value being the feature record ID and the label is the name of the lead source. */ for (Campaign f : [select Name,Type from Campaign f where f.Type =: category LIMIT 40000 ]){ optionList.add(new SelectOption(f.Id,f.Name)); } } return optionList; } }
- RossG
- May 12, 2014
- Like
- 0
Custom object field update trigger
I have a custom object (object__c) into which records are being bulk uploaded/inserted. There is a particular field on this object (appt__c) that includes a code (sometimes abbreviated text, sometimes alphanumeric, etc.) that corresponds to an appointment type.
I am trying to update a second field on the record (text__c) with a more "readable" text-version of the appointment type. For example, if "ov" is uploaded into the appt__c field, I want to update the text__c field with "office visit." There usually will be, however, multiple codes that correspond with the same text version. For example, all of the following might equal "office visit": "ov," "ov(15)," "office."
This seems like a relatively simple issue, but I can't seem to get to the answer. Anyone willing to offer any suggestions?
(p.s. I am currently doing this with a field replacement workflow, but there are so many apppointment type codes that I keep running up against limits in my field update formula.)
- PaulJS
- January 26, 2014
- Like
- 0
Test class for Messaging class
Hey guys-
I've got a simple messaging class that works great, but I need a solid test class for it.
All this is is a class that's called from a javascript custom button that is on the page layout of a custom object record. When someone click the button, it calls this class, and an email is sent out to the email you can see in the class (I've changed it for anonymity here to 'test@test.com')
global class CIFEmails { WebService static void SendEmailNotification(string id, string accountName) { //create a mail object to send a single email. Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); //set the email properties mail.setToAddresses(new string[] {'test@test.com'}); mail.setSenderDisplayName('Ping Salesforce'); mail.setSubject('A CIF Has Just Been Submitted to Contracts & Licensing for: ' + accountName ); mail.setHtmlBody('A Customer Information Form has just been Submitted to Contracts & Licensing.'+ 'To access the CIF, please go to the record in Salesforce, here: '+ 'https://cs15.salesforce.com/' + id); //send the email Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail } ); } }
So, I need no test class for my javascript button. But I do need a test class for the messaging class above.
Problem I see is the SF developer documentation is lacking on how to test emails sent via apex.
Anyone have any code I could take a look at that is a GOOD test class for this class? Doesn't have to be bulkified in this case since the class is only ever called from a custom button.
Thanks a lot for any help anyone can provide
- RossG
- September 04, 2013
- Like
- 0
Web to Lead failing as a result of AutoLead Convert - Many times posted and yet to find a solution
Hey there,
I have a problem which I have posted many times and I am yet to find a solution. Normally, the threads eventually just die. If an idea of what I have tried is what is needed. Here is a recent post:
I have an auto-leadConvert trigger which works perfectly, however my system needs to be designed so every new client comes through the web 2 lead on the website, it is then converted automatically into an account and a contact. When the trigger is active, it simply prevents the web2lead from creating the lead. I assume this is because so many processes are happening simultaneously. I have two options:
1. I can alter my code, so it still allows web2lead before automatically converting. This is my code:
AutoConvertLead Trigger
trigger ConvertLead on Lead (after insert, after update) {
for (Lead lead : Trigger.new) {
if (lead.isConverted == false) //to prevent recursion
{
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(lead.Id);
lc.setDoNotCreateOpportunity(true);
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
}
}
}
Or
2. I have altered the code, it now has another if statement that says the 'convertReady' field is checked. The web2lead was now creating leads, except I put in a timetriggered field update for the ConvertReady field to update to checked an hour after record creation. The rule just never activates. This is my other code:
trigger ConvertLead on Lead (after insert, after update) {
for (Lead lead : Trigger.new) {
if (lead.isConverted == false) //to prevent recursion
{
if (lead.ConvertReady__c == true) //To allow web to lead
{
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(lead.Id);
lc.setDoNotCreateOpportunity(true);
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
}
}
}
}
Please help me with a solution
- Developer.mikie.Apex.Student
- July 05, 2013
- Like
- 0
question on list syntax
Anyone know how I can add a soql statement to this:
public void createEngagementWhenNeeded1(List<Opportunity> opportunities)
Basically that's a list of opps. Is it possible to adda soql statement to that, like this:
List<Opportunity> opps = [SELECT Id,Services_to_be_Delivered_by__c,Probability,Threshold__c,Account.Id,Account.Name,Region__c,
CreatedById,Account.Region__r.OwnerId,Account.Region__r.RSA_Manager__r.Id,Professional_Services__c,
Name From Opportunity];
Not sure how to get that to work.
- RossG
- June 24, 2013
- Like
- 0