MK Partners Tips

Jotting directly into Salesforce

Last week, I started using Jott.com.  If you’re not familiar with their service, it is essentially a personal dictation secretary.  You call Jott.com, pick a contact from your address book and then start talking.  Jott.com transcribes your message and emails the person the resulting text as well as a link to listen to your recording.

We normally try to not excessively promote services and products on this blog, but we liked Jott.com so much that we decided to build Jott-2-Salesforce.  We leveraged Apex Email Services to automatically create a task in Salesforce every time we leave ourselves a message on Jott.  Here’s a generic version of the Class, have fun!

Global class Jott_Note_To_Self implements Messaging.inboundEmailHandler{

Global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope env ) {

    // Create an inboundEmailResult object for returning the result of the Apex Email Service
    Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
 
    // If unsubscribe is found in the subject line enter the if statement
        try {
             // Create a new Task
            Task t = new Task();
            t.Subject = email.subject;
            t.Description = email.plainTextBody;
            t.Status = ‘Not Started’;
            t.Priority = ‘Normal’;
            insert t;
         } catch (exception e) {
        }    

    // Return true and exit
    // True will confirm it is complete and no bounced email
    result.success = true;
    return result;
}   

static testMethod void testUnsubscribe() {

    // Create a new email and envelope object
   Messaging.InboundEmail email = new Messaging.InboundEmail() ;
   Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

   // test with subject that matches the unsubscribe statement
   email.subject = ‘test jott’;
   env.fromAddress = ‘support@salesforce.com’;
  
   // call the class and test it with the data in the testMethod
   Jott_Note_To_Self jott = new Jott_Note_To_Self();
   jott.handleInboundEmail(email, env );
                       
}

}

New Year’s Resolution 1: DeDuping Records

How many times have you found duplicate records in Salesforce?  I find them all the time, especially duplicate Leads.  Well, my first resolution this year is to identify all the duplicate Leads in the MK Partners instance of Salesforce.  Here’s how I’m going to do it:

  1. Determine what fields have to be the same in order for two records to be considered duplicates.  For this example, any records with the same email address are duplicates.
  2. Create a new field as follows:
    Datatype: Email
    Field Label: Unique Email
    Unique: Check this box!
  3. Using the Apex Data Loader, Extract a list of all Leads that have Emails, be sure to include the Lead Id and Email fields.
  4. Using the Apex Data Loader, run an update on Leads using the success file generated in step 3.  Map Id to “Id” and Email to “Unique Email”.

The resulting errors file will be a list of duplicate Leads and the Id’s of their duplicates.

This information is extremely useful as you no longer have to go randomly searching for duplicates, you have the complete list in a single file. 

If you’re new to Salesforce, you can paste the Id’s one by one into your browser (eg  www.salesforce.com/000000000000000000 ) to see more about the records and use the built in Merge functions. 

If you’re somewhat savvy, then you can update these records, mark them as duplicates, and notify their creators/owners that they need to fix the problem.

If you’re like me, then you’ve probably already created an s-control that can merge up to 200 pairs of duplicate records at a time.

Either way, you’re starting the new year with a cleaner set of data!

Happy New Year from MK Partners.

Hidden Profile causing problems

Working on a client’s project, one of our consultants was unable to deactivate an Opportunity Record Type that was no longer needed.  The error message stated that the Record Type could not be deactivated because it was the default Record Type for a Profile named “Salesforce Administrator”.

Normally, this wouldn’t be a big deal, we would go to the Profile and change the default Record Type.  Unfortunately, this is no ordinary Profile.  It is a hidden, API Only User, standard profile that is not displayed on your list of Profiles and does not even have an Opportunities option in its Record Type section.  This posed quite a problem, as we really wanted to deactivate this Record Type.

Hidden Profile

The solution, we took the URL for editing the Opportunity Record Type on another profile and replaced the Profile Id and Profile Name with that of our hidden profile.  The format of the URL is below, we’ve replaced our actual Profile Id with {!Profile.Id}. 

https://na1.salesforce.com/setup/ui/profilerecordtypeedit.jsp?id={!Profile.Id}&tid=Opportunity&pn=Salesforce+Administrator

This type of URL handywork can be used in a variety of places in Salesforce and is a good trick to have.

No More Weekend Tasks

If you’re like us, you probably have a lot of Workflow Rules and Tasks setup in Salesforce. It’s a great feature that helps to automate processes and it ensures accurate and timely notification across your organization.

One thing that has always bothered me about Salesforce’s Workflow is that it doesn’t take weekends into consideration (unlike Case Escalation Rules). Well if you have access to Apex Code, here is a simple Task Trigger that will update Tasks created with a due date on Saturday or Sunday to instead have a due date on Monday or Tuesday.

Just create a new Task Trigger with the following code:

trigger WeekendTasks on Task (before insert) {
	for (Task tas : Trigger.new) {
			Date origin = Date.newInstance(1900,1,6);
			Date due = tas.ActivityDate;
			Boolean reminder = tas.IsReminderSet;
			Integer x = origin.daysBetween(due);
			Integer day = Math.mod(x,7);
			if (day < 2 ) {
				tas.ActivityDate = (due + 2);
				if (reminder == true ) {
					Datetime rem = tas.ReminderDateTime;
					tas.ReminderDateTime = (rem + 2);
				}
			}
	}
}

Special thanks to Eric Bezar at The Official Salesforce Blog for help with the original formula.

Tracking the duration of a call

If you haven’t joined the CTI bandwagon, then you probably have a hard time tracking the duration of your calls (tasks) in Salesforce. At MK partners, we’re already enjoying the benefits of the Skype CTI Connector, but for one of our clients it wasn’t an option. So, we developed a simple process to help them capture the amount of time their reps spend on logging calls in Salesforce. It’s so simple in fact that we’re giving it away, just follow these two steps:

  1. Create a new Activity custom field as follows:
    Datatype: Date/Time
    Field Label: Call Start
    Default Value: NOW()
    Field Level Security: Make it Visible to all profiles
    Page Layouts: Don’t display it on any of your page layouts
  2. Create a 2nd Activity custom field as follows:
    Datatype: Formula
    Field Label: Call Duration
    Formula Return Type: Text
    Formula:
    TEXT(CEILING(0.24*FLOOR(100*(CreatedDate -Call_Start__c))))
    & “:” &
    RIGHT(“0″&TEXT(ROUND(MOD((1440*(CreatedDate-Call_Start__c)),60)+0.5,0)-1),2)
    Profiles/Field Level Security: Make it Visible to all profiles
    Page Layouts: Display it on your Task page layouts

That’s it! You now have a field that will track the amount of time between when you click “Log A Call” and “Save”. Now you just have to create the reports and dashboards to analyze and improve your call efficiency. Good Luck!

Creating a Formula Field to Sort Records in True Alphabetical Order

Frequently, many users experience frustration when attempting to sort data to their exact specifications. These frustrations often occur because the data entered into Salesforce differs from the type of sort desired by the user. An example of this situation could occur if you wanted to track your DVD collection and sort through the albums alphabetically. For instance, if my DVD collection includes the shows Arrested Development, The Office, and The New Adventures of Old Christine, it would not benefit me to search through all of my DVD’s that begin with the word ‘The’ because my alphabetical sort will recognize the word ‘The’ in quest to alphabetize my DVD collection. As a result, the following formula field explains how a user can sort through their data in true alphabetical order.

  1. Select a text-based formula field
  2. Choose to create an advanced formula
  3. Develop an IF/THEN logic statement to define your sort.
    • In this case, IF a DVD begins with the word ‘The’, then I want to do an alphabetical sort that ignores the word ‘The’.
  4. Select the IF function from the function box on the right side of the create an advanced formula screen.
  5. Add an open parentheses, type the word ‘BEGINS’, add an open parentheses and quotes around the text to be ignored and close the parentheses.
    • In this case, the formula should read IF(BEGINS(Name, “The”),
  6. Now select the MID function in the function box on the right side of the screen to indicate the new starting position of your sort. The starting position will correlate with the number of characters contained in the text you want to ignore.
    • In this example, the word “The” is 3 characters, but a space will come before the next word, which means we want to ignore the first 4 characters.
  7. After selecting the MID function, add an open parentheses, type Name, add a comma, type the number of characters to be ignored, add another comma, select the maximum amount of characters in your text field and close the parentheses.
    • The above formula would now read IF(BEGINS(Name, “The”), MID(Name, 4, 251)
  8. If the only word to be ignored is the word “The”, you must add the following text to complete the formula: ,Name)
  9. If you have other parameters to include in your sort, you must specify the amount of characters to be ignored.
    • For example, if you own the DVD “The New Adventures of Old Christine”, you might want the alphabetical sort to find this record by the word ‘Christine’. In this situation, you must add a formula that would read IF(BEGINS(Name,”The New Adventures of Old”, MID(Name, 26, 229). Now we have created a formula to ignore the first 26 characters of text, which will enable the sort to only recognize the word Christine.

Our two rules would be entered into a custom formula as the following: IF(BEGINS(Name, “The New Adventures of Old”), MID(Name,26,229) ,IF(BEGINS(Name, “The”), MID(Name,4,251) , Name))

Other information to know: When creating multiple rules to sort data, the longest rules must be entered first and followed by rules to ignore fewer characters. Additionally, you must add a closed parentheses to end of the formula for each custom rule you have created.

In summary, developing a custom formula field to sort records in true alphabetical order is easily attainable by creating IF/THEN statements to outline your specific data sort.

Reporting on the number of unique parent objects with child objects

Have you ever tried to find out how many of your Accounts have Opportunities? It sounds simple at first, but when you run a report on Opportunities you can only report on the total number of Opportunities, not Accounts. Here’s a simple solution:

  1. Create a new Formula Field on Accounts
  2. Name the field “Account Counter”
  3. Choose Number for the Output Type
  4. Just type in the number 1 for your formula
  5. Save the new field

Now go back to your report on Opportunities, on the Select the information to summarize step, check the Sum box next to your new “Account Counter” field and click Run Report.

See what happened? At the bottom of the report, you now have the total number of Opportunities as well as the number of unique Accounts.

Update Record Types from the Edit Page

I’m sure you noticed a long time ago that in order to change the Record Type of a record in Salesforce you have to be on the View page for that record, not the Edit page. If you’re like me, then this makes no sense at all to you. Most users do not distinguish between changing a Contact’s phone number and changing its Record Type, so why do you have to go to two different pages to perform the two changes?

Well now you don’t, a long time ago we implemented Workflow Rules and Workflow Field Updates to automate changing Record Types based on changes made on an Edit page. For instance, let’s say you have a picklist field on Accounts called “Type” with values “Prospect” and “Customer”. And let’s also say that you have Account Record Types with the same names.

You can setup one Workflow Rule on Accounts that runs when the following criteria is met:

  • Type equals Prospect
  • Account Record Type not equals Prospect

Then setup a Workflow Field Update to change Account Record Type to Prospect.

You can then setup a second Workflow Rule on Accounts that runs when the following criteria is met:

  • Type equals Customer
  • Account Record Type not equals Customer

Setup another Workflow Field Update to change Account Record Type to Customer.

That’s it! Now remove the Account Record Type from your page layouts and never worry about it again!

Arrowpointe’s Sidebar Summary in the forefront

Last week Scott @ Arrowpointe posted a great alternative to the dashboard component on the Home Tab. He built an s-control that can be used in conjunction with a Home Page Component to truly provide a quick snapshot of your key metrics.

Scott’s concept is simple yet highly effective, so we’ve leveraged his code to take the component out of the Sidebar and into the main portion of the screen. This helps overcome the current limitation of only 3 dashboard components on the Home Tab. Take a look:

Configuration of the statistics requires basic understanding of s-Controls, but it would be great if someone put together a package that utilized custom objects to provide a friendly user interface.