We use Elluminate Live! for some of our meetings, and it has always bothered me that I have to launch the browser to use Elluminate especially for reoccurring meetings. So one afternoon I set out to fix this problem. I wrote the following script and have been using it for about a month now without any issues. You can set the parameters at the head of the script if you have a reoccurring meeting you want to use, or set the parameters at run time (or in an alias for multiple reoccurring meetings) if you need too.
The only prerequisite for this script is to have javaws installed an in your PATH.
Today I started setting up the repository for people to use to install the Solenopsis rpm. The problem is I want to be able to build the rpm (via Jenkins) and push it to a remote server and automatically have the repo rebuild when it sees an rpm updated or added to the directory.
To do this, I wrote a small python script that can be run and backgrounded. It sends a pushover notification and runs createrepo against the target directory.
The other day I came across a problem where sending in a blank field to Salesforce via SOAP was not nulling out the field. Instead, the enterprise WSDL was treating this as if nothing was sent, and therefore not updating the field at all. This make sense. If you were to send a sparse data structure over with only fields you want to update, you wouldn’t want to either have to provide the current value of every field or have them all nulled out. So, how do you null out a field with SOAP via the enterprise (or partner) WSDL in Salesforce?
NOTE: This is input is formatted for SoapUI, it may differ depending on the client you are using to send the SOAP message. The key take away is fieldToNull urn.
Lets start with a simple example of updating a field via the Enterprise WSDL
This will set the CustomField__c on the Contact to “Yay! Data”
To null out this field we simply send the field name as part of the fieldsToNull list
One thing that comes up a lot in the in the #salesforce IRC channel is doing dynamic Visual Force driven off of picklists. So, let’s buckle up and get to it.
In this simple example we are going to make an extension to the case page. On this page we are going to us a custom Product/Version object to display on the page. The product list well be determined on the start/end date of the product. And the version will be driven by the currently selected product. Product
Name – The name of the product
Currently_Supported__c – Formula based on StartDate__c and EndDate__c (Integer version of a boolean)
StartDate__c – The date the product should be shown (Rollup min from the version)
EndDate__c – The date the product should be hidden (Rollup max from the version)
Name – The name of the version
Currently_Supported__c – Formula based on StartDate__c and EndDate__c (Integer version of a boolean)
StartDate__c – The date the version should be shown
EndDate__c – The date the version should be hidden
Product__c – The product the version is related to
These methods are simple util methods to get product information and version information
The controller has the getters and setters for the product and version. But most importantly the getters for productList and versionList. The versionList is triggered off the record’s product. The other part of this is that for whatever reason (I couldn’t find a good one) is the getRecord does not include the changes made to the Product__c and Version__c field, so you’ll need to set them by hand in the doSave method.
One thing to note is since this is all done in the controller extension and since get and set use the Id, the select list will have the correct thing set when editing an existing record.
Visual Force Page
The key parts of this is that the actionRegion surrounds both the item changing (product) and the dependent item (version). If you had a third picklist you wanted to trigger on you could add another actionSupport item and tell it to rerender that third list.
Dependent picklists are not very hard to do as long as you remember the actionRegion around both the source and target, and making sure to get the data from the picklist prior to upserting your record.
One thing I find myself doing a lot is swapping two files in bash. I thought about making this into a bash script then I realized 1) that’s over kill and 2) not as portable as I want. So, if you add this to your .bashrc then re-source it, you’ll be able to run the command swap to switch two files
Scheduled actions in Apex are great to use when you need to have a section of code run at a particular time in the future and Time-Based workflows will not work. In the example below I’ll talk about how to schedule code to run at the first of every month, in addition talk about some constructs you can use to make your life easier when you have to redeploy/change this code
The key part of the apex class is that it must implement Schedulable and it must have an excecute method.
Now, we can fill out the class. Below is an example where we iterate through all of the accounts of a specific record type and insert a new list of MyObject based on that account. This could be as complex as you want.
To schedule this class we could call it from any number of places, such as a VisualForce page, a Trigger or the Developer Console. Since scheduled classes cannot be pushed out or changed when there are jobs in the queue we want to add a helper method to schedule this job. In our instance it will only be ran once a month, so we include our CRON_EXP as a static variable (for easy use) and to reduce the change of mis-scheduling.
To reset our schedule all we have to do is use type the following into the Developer console.
And by looking in Setup->Monitoring->Scheduled Jobs we can see that our scheduledMonthly class is there.
There are seven fields for Salesforce’s cron syntax, unlike *nix’s 5 fields.
Day of month [1-31]
Month [1-12 or JAN-DEC]
Day of week [1-7 or SUN-SAT]
There are also some special characters you can use:
, used to delimit values [hours, day of month, month, day of week, year]
- used to specify a range [hours, day of month, month, day of week, year]
* used to specify all values [hours, day of month, month, day of week, year]
? used to specify no specific value [day of month, day of week]
/ used to specify increments [hours, day of month, month, day of week, year]
L used to specify the end of a range [day of month, day of week]
W used to specify the nearest weekday [day of month]
# used to specify the nth day of the month [day of week]
Testing for scheduled apex may seem confusing but it’s very straight forward. Like @future calls, scheduled apex will not fire until after the Test.stopTest() has been run. In the test below we test the following:
The Cron Expression is the same
The job has not been triggered yet
The scheduled date is correct
No MyObjects were created
One object was created after the scheduled job was ran
Limitations / Notes
There are three big limitations / notes about scheduled Apex
It will be put on the queue at the given time, it is not guaranteed to run at that time.
You can only have 25 classes scheduled at a time
You cannot use getContent or getContentAsPDFPageReference
In a previous post I discussed how to test Salesforce webservices with soapUI. In this post I will show how to use the “default” methods inside the enterprise WSDL.
First we need to login to Salesforce and get our session Id. Under the SoapBinding list, expand login and choose Show Request Editor. After opening the request editor we need to remove the extra headers we don’t need, and fill in our username and password.
Then press the “play” button to send the request
Now in the resulting XML we can pull out our session Id
And we can pull out our server Url
Adding the new endpoint
If we create a new query request and remove the unneeded headers and insert our session Id and run the request you get the following error:
UNKNOWN_EXCEPTION: Destination URL not reset. The URL returned from login must be set in the SforceService
To fix this issue we need to add a new end point to our SOAP request. Using the server Url obtained during login we can add it to our request
And now we can rerun our new request with the correct endpoint
Unlike custom webservices which include the Salesforce endpoint as part of the WSDL the standard Salesforce enterprise WSDL only has the test or login url included. Because of this, we need to use the returned server url to set our end point.
The more moving pieces you have with triggers and classes the more you want to reduce the number of SOQL queries. One way to do this is to have Utility classes that do a lot of the heavy lifting. The problem with this is that you don’t want to call a utility method that does a query every time, because if you call it from different triggers you’ll end up with multiple calls. This is where overloading static variables can come in.
Lets say you have a trigger on a Contact that needs information from our mostly static MyObject__c and then the Contact trigger then updates a Case. The Case trigger also need information from the MyObject__c. Normally this would require two SOQL queries even if it was in a utility class. We can use some of the built-in functionality in Apex to overload a static variable.
In the trigger where we want to use the MyObject instance we can do the following
Now, the next time the map or list are used in the same execution we will have it “cached” and will not have to make an additional query.
Anyone that has ever had multiple triggers on objects in Salesforce knows that it can be very painful to manage them. Because of the way Salesforce chooses to run the triggers your code can be run in a non-deterministic order. In addition to this, having to sort through multiple files to find the one piece of code you are looking to update can be painful.
To combat this, you can take your triggers and condense them down into a single trigger and a single class. Inside this class you would have a method containing each of your individual triggers.
In the examples below we will be creating a trigger on the MyObject__c to do awesomness. In the example we do not cover the case of undelete.
The trigger is quite simple, all it does is call the a static method of the class with the correct parameters.
This is where the meat of the functionality exists. The constructor sets up the maps and lists as well as the booleans. Inside your doAwesomeness method you can check to the booleans isUpdate, isDelete, isInsert to make your routing determination. If you do not want the method to run, just return out of it and the execution will stop. MyObjectTrigger.cls
We’ve been using this method for almost a year now and it works really well. If you need data to persist between methods this way works wonderfully. Just create a global variable and set it up in your constructor. This will save you SOQL calls and if done correctly could save you DML operations
Since I switched over to using vim as my primary mode of Salesforce development, I’ve been asked several times how I’ve configured vim. Well, it’s about time I show the man behind the curtain. My primary vim config file is quite large now, but I’ve condensed it down to the parts that I think are most pertinent to Salesforce development.
Now vim is great for editing but where I think it shines the most is in highlighting. I’ve taken the standard java vim file and have modified it for use with the Apex language. To use it, download the apex.vim file and place it in your syntax directory for vim.
To make it work for just your user you can place the file in ~/.vim/syntax/ but you will need to also symlink (or copy) the html.vim file into that directory.
To make it work for all users on the system you can just place the file into your global syntax directory. For fedora and probably most unix systems it is /usr/share/vim/vim73/syntax/
Now that we’ve got highlighting installed, lets get vim to use it. First we need to create our backup and swap directories. We do this to keep extra files out of our Salesforce directory so that we don’t try to deploy them (or commit them to our repo).
mkdir ~/.bak ~/.swp
Now we can add / replace the following options into our .vimrc file
You might need to edit the values for tabstop, shiftwidth and softtabstop for your coding standards but 4 is what we use.