Workflow ISCHANGED() translated to Apex trigger
Workflow is great. I can simply and declaratively make changes, and can easily update things like email templates, criteria, tasks, etc. without using Eclipse and writing/running unit tests.
Sometimes, however, workflow isn’t enough; we need to use a trigger.
Today, I had a use-case that when a DateTime field is filled, a contact (identified via a lookup on a parent object – so a grandparent record) should receive a notification. That’s easy enough to do with a ISCHANGED(DateTimeField__c) workflow criteron, but the Email Alert can’t “find” the contact. A trigger is necessary.
Here’s how I coded the trigger:
trigger InterviewUpdates on Interview__c (after update, before update) {
if(Trigger.IsBefore){
for(Interview__c i : Trigger.New){
DateTime dt = i.Date_and_Time__c;
if(Trigger.oldMap.get(i.id).Date_and_Time__c != dt){
// Send email to applicant, passing Interview, DateTime, and Contact
// (which we found via a query coded outside the loop to avoid governor limits)
}
}
}
}
I’ve left out a lot of parts here, but I hope that the main bit of using Trigger.oldMap to find the old value and compare it to the new one comes through.
Happy coding!
Best Practice: Multiple Chatter Posts of the Same File
Filed under: Configuration, Native Application, Salesforce CRM, Tips and Tricks
Salesforce Administrators learn to remind users: “Search before you create a new lead.” Pretty simple, right? Duplicated records are a pain.
Then why do I see some very accomplished Salesforce users in the Dreamforce app posting duplicate Content/Files in Chatter?
Here are some examples from the Files tab:
The better thing to do – assuming that you need to post the same file multiple times (this should be rare, as it might be considered Chatter Spamming, but when referring multiple users or groups to a document, it can come in handy) is to upload the file ONCE and use references to it in subsequent feed posts.
This has a bonus: Better maintenance! Instead of other users not knowing which file to follow if they want to be notified anytime that file is updated, just ensure that there is only ONE copy in the org, and everyone can follow that. This is especially useful for legal documents, employee handbooks, FAQs, Dreamforce App Codes of Conduct… you get the idea.
Not sure how it’s done? Here are a few screenshots:
And there you have it! Go forth and attach! … and after that, just link.
Next Birthday Formula
How would you display your Contacts with upcoming birthdays? I’ve seen people use “Birthdays This Week,” “Birthdays This and Next Week,” and other reports to display the list.
I’ve also seen requirements for showing a person’s next birthday, to trigger an automatic email to each Contact on his/her birthday. Let’s see how it’s done:
if(
Month (Birthdate) < = Month(Datevalue( NOW() ) ),
if ( Month (Birthdate) < Month(Datevalue( NOW() ) ),
DATE( YEAR( DATEVALUE( NOW() ) ) + 1 , MONTH( Birthdate ) , DAY( Birthdate ) ),
if ( Day (Birthdate) < Day ( Datevalue ( NOW() ) ),
DATE( YEAR( DATEVALUE( NOW() ) ) + 1 , MONTH( Birthdate ) , DAY( Birthdate ) ),
DATE( YEAR( DATEVALUE( NOW() ) ) , MONTH( Birthdate ) , DAY( Birthdate ) )
)
),
DATE( YEAR( DATEVALUE( NOW() ) ) , MONTH( Birthdate ) , DAY( Birthdate ) )
)
Next, use Batch Apex to send an email daily to all people where Next_Birthday__c == date.today(). Easy!
Now we can put this into a report and a dashboard showing the next “n” birthdays. Sure, it’s possible that more than n people will have a birthday on a given day, but at least you know that the emails will go out to each of them! If you want to see everyone with birthdays in a certain range, make a custom report and click through from a dashboard or a custom link.
Enjoy!
PageReference Best Practice
I've seen a lot of coders put the following into their custom Visualforce controllers:
public PageReference customsave() {
try{
insert acct;
} catch (DMLException e) {
/*do stuff here*/
}
PageReference acctPage = new PageReference ('/' + acct.id};
acctPage.setRedirect(true);
return acctPage;
}
I've decided that I don't like this approach. It feels too much like a URL hack, and though I'm sure that it will always work (meaning that salesforce.com will never change its way of referring to a record by /<recordID>), I'd like to suggest a different method that may use more resources, but will leverage standard controllers, possibly future-proofing the application:
public PageReference customsave() {
insert acct; //Error handling removed for brevity. ALWAYS try/catch!
ApexPages.StandardController sc = new ApexPages.StandardController(acct);
PageReference acctPage = sc.view();
acctPage.setRedirect(true);
return acctPage;
}
What do you think? Does anyone have coding-style tips to share?










