<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Perspectives on Salesforce.com &#187; Tips</title>
	<atom:link href="http://sfdc.arrowpointe.com/taxonomy/category/Tips/feed" rel="self" type="application/rss+xml" />
	<link>http://sfdc.arrowpointe.com</link>
	<description>Authored by Scott Hemmeter of Arrowpointe Corp, this blog is written from the perspective of a Salesforce.com solution provider and contains information on Arrowpointe's AppExchange products as well as tips, findings, sample code, functionality wishes, etc.</description>
	<pubDate>Fri, 31 Oct 2008 20:15:16 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<item>
		<title>Campaign Member Summary using Google Charts</title>
		<link>http://sfdc.arrowpointe.com/2008/10/31/campaign-member-summary-using-google-charts/</link>
		<comments>http://sfdc.arrowpointe.com/2008/10/31/campaign-member-summary-using-google-charts/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 20:15:16 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[APEX Code]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=461</guid>
		<description><![CDATA[I was inspired by Sam Arjmandi&#8217;s post about embedding Google Charts into VisualForce pages.  I have a use case that requires a little different approach.  I needed to get a quick view of the Campaign Member Statuses for a Campaign.  I went ahead and started with Sam&#8217;s example and tweaked it for my purpose.  Here&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I was inspired by <a href="http://salesforcesource.blogspot.com/2008/10/how-to-easily-bring-graphical-charts.html" target="_blank">Sam Arjmandi&#8217;s post</a> about embedding Google Charts into VisualForce pages.  I have a use case that requires a little different approach.  I needed to get a quick view of the Campaign Member Statuses for a Campaign.  I went ahead and started with Sam&#8217;s example and tweaked it for my purpose.  Here&#8217;s the result!</p>
<p><img class="aligncenter size-full wp-image-462" title="vfcampaignchart" src="http://sfdc.arrowpointe.com/wp-content/images/vfcampaignchart.png" alt="" width="457" height="238" /></p>
<p>It&#8217;s an embedded VisualForce component in the Results section of my Campaign page.  It shows a quick count for each Member Status that is being used.  To get it going in your org, here&#8217;s what you need.</p>
<p><strong>VisualForce Page</strong></p>
<p>It&#8217;s a simple page containing 1 DIV so that I can set the background color to match that of a Page Layout.  Other than that it&#8217;s just an image returned from <a href="http://code.google.com/apis/chart/">Google Charts</a>.  There is a lot of flexibility with Google Charts.  Therefore, I made it so most of the URL can be tweaked in VisualForce. Only the data values and its labels come from the controller.  This is nice because you can edit VF in a production org, but you can&#8217;t edit Apex.  This will let you change things like width, height, chart colors, chart type, etc.</p>
<pre class="syntax-highlight:html">

&lt;apex:page standardController=&quot;Campaign&quot; extensions=&quot;VFController_CampaignMemberStatusChart&quot;&gt;
    &lt;style&gt;
        #DIV_Container{padding: 0; margin: 0; background-color: #F3F3EC;}
    &lt;/style&gt;
    &lt;div id=&quot;DIV_Container&quot;&gt;
        &lt;!-- See http://code.google.com/apis/chart/ for more info on customizing the chart --&gt;
        &lt;apex:image url=&quot;http://chart.apis.google.com/chart?cht=p3&amp;chs=1000x125&amp;chf=bg,s,F3F3EC&amp;chco=CC9933{!chartData}&quot;&gt;&lt;/apex:image&gt;
    &lt;/div&gt;
&lt;/apex:page&gt;
</pre>
<p><strong>Apex Controller</strong><br />
The controller is an extension of the Campaign standard controller.  This is so the VisualForce page becomes an option to include on a Campaign Page Layout.  The method that does all the work is getChartData.  It gets the available Campaign Member Statuses and then queries the Campaign Member object for that Campaign and adds a data/label value for each one.  It then returns a query string that you include into the Image src on the Visual Force page.</p>
<p>I am bad at Test classes, but there is 1 in there that passes and should be good enough.  This functionality is pretty harmless.</p>
<pre class="syntax-highlight:java">
public class VFController_CampaignMemberStatusChart {

	private final Campaign camp;

	public VFController_CampaignMemberStatusChart(ApexPages.StandardController stdController) {
		this.camp = (Campaign)stdController.getRecord();
	}

	public String getChartData() {

		// The list of chart items
		List&lt;ChartDataItem&gt; items = new List&lt;ChartDataItem&gt;();

		// List of valid Campaign Member Statuses for the Campaign
		List&lt;CampaignMemberStatus&gt; list_cms = [select Id, Label from CampaignMemberStatus where CampaignId = :camp.id];

		// Loop through each Campaign Member Status, get a count of Campaign Members and add it to the items list
		for (CampaignMemberStatus cms:list_cms) {
			integer Count = [select count() from CampaignMember where CampaignId = :camp.id AND Status = :cms.Label];
			if (Count &gt; 0) {
				items.add(new ChartDataItem(cms.Label, Count.format()));
			}
		}

		// Initialize Strings
		String chd = &#039;&#039;; // Data
		String chl = &#039;&#039;; // Labels

		for(ChartDataItem citem : items) {
			chd += citem.ItemValue + &#039;,&#039;;
			chl += citem.Label + &#039; (&#039; + citem.ItemValue + &#039;)|&#039;;
		}

		//remove the last comma or pipe
		if (items.size() &gt; 0) {
			chd = chd.substring(0, chd.length() -1);
			chl = chl.substring(0, chl.length() -1);
		}

		// We are only returning the values and labels. The rest of the URL string is in the VF page
		String result = &#039;&amp;chd=t:&#039; + chd + &#039;&amp;chl=&#039; + chl; // &amp;chl returns with labels pointing to pie pieces
		//String result = &#039;&amp;chd=t:&#039; + chd + &#039;&amp;chdl=&#039; + chl; // &amp;chdl returns with labels in a legend

		return result;
	}

	// Class holding each chart data item
	public class ChartDataItem {
		public String ItemValue {get; set;}
		public String Label {get; set;}

		public ChartDataItem(String Label, String Value)
		{
			this.Label = Label;
			this.ItemValue = Value;
		}
	}

	static testMethod void testVFController_Sidebar_Summary() {

		// Create Campaign
        Campaign c = new Campaign();
        c.Name = &#039;Test Campaign&#039;;
        insert c;

        // Create Lead
        Lead l = new Lead();
        l.LastName = &#039;Last Name&#039;;
        l.Company = &#039;Company&#039;;
        insert l;

        // Create Campaign Member
        CampaignMember cms = new CampaignMember();
        cms.CampaignId = c.id;
        cms.LeadId = l.id;
        insert cms;

		test.startTest();

		ApexPages.StandardController sc = new ApexPages.StandardController(c);
		VFController_CampaignMemberStatusChart controller = new VFController_CampaignMemberStatusChart(sc);
		String s1 = controller.getChartData();

		test.stopTest();
	}

}
</pre>
<p><strong>Page Layout</strong><br />
When you add it to the Page Layout, make the height of the component the same as the height you specified in the VF page&#8217;s image src for Google Charts.  In this example, it&#8217;s 125.  Doing this will ensure the background colors match your Page Layout.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/10/31/campaign-member-summary-using-google-charts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sidebar Summary using Visualforce</title>
		<link>http://sfdc.arrowpointe.com/2008/09/17/sidebar-summary-using-visualforce/</link>
		<comments>http://sfdc.arrowpointe.com/2008/09/17/sidebar-summary-using-visualforce/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 06:11:41 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[APEX Code]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[Arrowpointe Products]]></category>

		<category><![CDATA[Configuration]]></category>

		<category><![CDATA[Sidebar Summary]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=395</guid>
		<description><![CDATA[About a year ago, I posted about the Sidebar Summary.  The Sidebar Summary exists in the Salesforce.com sidebar and displays the counts of some important queries.  The counts are also hyperlinks to a view or report representing that query.  It&#8217;s a very handy thing to have in your sidebar and I use it all the [...]]]></description>
			<content:encoded><![CDATA[<p>About a year ago, I posted about the <a href="http://sfdc.arrowpointe.com/2007/08/28/sidebar-summary/" target="_self">Sidebar Summary</a>.  The Sidebar Summary exists in the Salesforce.com sidebar and displays the counts of some important queries.  The counts are also hyperlinks to a view or report representing that query.  It&#8217;s a very handy thing to have in your sidebar and I use it all the time for my own work.  However, because it&#8217;s an s-Control, it runs a little slow.  In fact, it ran slow enough to make me uncheck the user interface option &#8220;Show Custom Sidebar Components on All Pages&#8221;.</p>
<p style="text-align: center;"><img class="size-full wp-image-398 aligncenter" title="sidebarsummary" src="http://sfdc.arrowpointe.com/wp-content/images/sidebarsummary.png" alt="" width="353" height="310" /></p>
<p>I changed it into a Visualforce page with a custom Apex controller and now it runs super fast and I am able to keep the &#8220;Show Custom Sidebar Components on All Pages&#8221; option turned on and see it on every page I go to.  There&#8217;s a bit of hardcoding in here, but it gets the job done pretty well.  Bye bye s-Control.</p>
<p><span style="text-decoration: underline;"><strong>Visualforce</strong></span></p>
<p>The Page is almost all raw HTML.  The only dynamic thing in there are the count values.  Each one retrieves the value from a specific &#8220;get&#8221; method in the controller.  If you like the queries I use, then the only thing you&#8217;ll need to confirm are the URLs that get linked to.  The first 2 go to Views in my Org and the last 2 go to Reports in my Org.  You&#8217;ll need to change those URLs.</p>
<p>I named the VF Page &#8220;<span id="j_id0:theTemplate:j_id7:j_id8:j_id16:j_id17">SidebarSummary&#8221;.</span></p>
<pre class="syntax-highlight:html">

&lt;apex:page controller=&quot;VFController_Sidebar_Summary&quot; sidebar=&quot;false&quot; showHeader=&quot;false&quot; standardStylesheets=&quot;true&quot;&gt;
&lt;style type=&quot;text/css&quot; media=&quot;all&quot;&gt;
body{margin: 0; padding: 0; color: #000000; background-color: #E8E8E8;}
#DIV_Container {background-color: #F3F3EC;}
&lt;/style&gt;
&lt;div id=&quot;DIV_Container&quot;&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Unread Leads&lt;/em&gt;:  &lt;/td&gt;&lt;td&gt;&lt;a href=&quot;/00Q?fcf=00B30000005JhsT&quot; target=&quot;_parent&quot;&gt;&lt;b&gt;{!UnreadLeads}&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Leads - Not Contacted&lt;/em&gt;:  &lt;/td&gt;&lt;td&gt;&lt;a href=&quot;/00Q?fcf=00B30000005Jhru&quot; target=&quot;_parent&quot;&gt;&lt;b&gt;{!NotContactedLeads}&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Oppty - Next 30 Days&lt;/em&gt;:  &lt;/td&gt;&lt;td&gt;&lt;a href=&quot;/00O30000001aEHV&quot; target=&quot;_parent&quot;&gt;&lt;b&gt;{!Next30DayOppty}&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Oppty - Past Due&lt;/em&gt;:  &lt;/td&gt;&lt;td&gt;&lt;a href=&quot;/00O30000001aEHV&quot; target=&quot;_parent&quot;&gt;&lt;b&gt;{!PastDueOppty}&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/apex:page&gt;
</pre>
<p><span style="text-decoration: underline;"><strong>Apex</strong></span></p>
<p>The controller has a method for each query to be run.  Each query is a count() query and returns an Integer.  At the end is a really lame Test method, but it does get 100% of the code covered.  I am certain the code works, so I didn&#8217;t do too much with the Test method.  Salesforce just requires the code to be tested.</p>
<pre class="syntax-highlight:java">

public class VFController_Sidebar_Summary {

public Integer getUnreadLeads() {
return [
select count() from Lead
where IsConverted = False
AND IsUnreadByOwner = TRUE
];
}

public Integer getNotContactedLeads() {
return [
select count() from Lead
where IsConverted = False
AND Status = &#039;Open - Not Contacted&#039;
];
}

public Integer getNext30DayOppty() {
return [
select count() from Opportunity
where IsClosed = False
AND (CloseDate = Next_N_DAYS:30 OR CloseDate = TODAY)
];
}

public Integer getPastDueOppty() {
return [
select count() from Opportunity
where IsClosed = False
AND CloseDate &lt; TODAY
];
}

static testMethod void testVFController_Sidebar_Summary() {
Test.setCurrentPageReference(new PageReference(&#039;Page.SidebarSummary&#039;));
VFController_Sidebar_Summary controller = new VFController_Sidebar_Summary();
Integer i1 = controller.getUnreadLeads();
Integer i2 = controller.getNotContactedLeads();
Integer i3 = controller.getNext30DayOppty();
Integer i4 = controller.getPastDueOppty();
}

}
</pre>
<p><span style="text-decoration: underline;"><strong>Homepage HTML Component</strong></span></p>
<p>I created a component for the Narrow side and put the following HTML into the editor.  Essentially, you create an IFRAME and embed the VF page into it.  I found a (unsupported) trick on the forums to remove the developer bar from a page.  Just add <strong>?core.apexpages.devmode.url=1</strong> to the URL.  This will turn off development mode when that page is rendered.  This is important for this little iFrame page on the sidebar.  From what I&#8217;ve gathered, this hack is not supported and could change at any time.</p>
<p>The code below should work for you.  The only thing you might need to change is the Page URL if you didn&#8217;t name your page SidebarSummary and the height of it.</p>
<pre class="syntax-highlight:html">

&lt;iframe src=&quot;/apex/SidebarSummary?core.apexpages.devmode.url=1&quot; frameborder=&quot;0&quot; height=&quot;100&quot; width=&quot;100%&quot;&gt;&lt;/iframe&gt;
</pre>
<p>Let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/09/17/sidebar-summary-using-visualforce/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bulkifying a Trigger (an example)</title>
		<link>http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/</link>
		<comments>http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 23:11:11 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[APEX Code]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=372</guid>
		<description><![CDATA[Back in June, I blogged about a trigger I made to auto-create a Campaign Member record for new Leads if the Lead Source value matched the Name of an existing Campaign.  Steve Andersen rightfully commented on that post about the need to bulkify the trigger.  I have been pretty slow in learning Apex and over [...]]]></description>
			<content:encoded><![CDATA[<p>Back in June, I <a href="http://sfdc.arrowpointe.com/2008/06/19/auto-create-campaign-members-for-new-leads/" target="_blank">blogged about</a> a trigger I made to auto-create a Campaign Member record for new Leads if the Lead Source value matched the Name of an existing Campaign.  <a href="http://www.gokubi.com" target="_blank">Steve Andersen</a> rightfully commented on that post about the need to bulkify the trigger.  I have been pretty slow in learning Apex and over the past week or so things have started clicking for me.  I am now (finally) beginning to &#8220;get it&#8221;.  With the help of <a href="http://www.mkpartners.com" target="_blank">Matt Kaufman</a> and a friend at Salesforce, I have come to understand Apex a bit more and can much more easily apply it to my day to day Salesforce work.</p>
<p>Therefore, I thought I should correct the trigger I wrote and make it bulkified.  This should serve as a good before and after example of a trigger that accomplishes the same thing, but is now bulkified.  </p>
<p><strong>The original Trigger</strong><br />
Below is how the trigger looked originally.</p>
<pre class="syntax-highlight:java">
trigger Create_CampaignMember_For_New_Leads on Lead (after insert) {

	try {	

		if (Trigger.new.size() == 1) {

			List &lt;CampaignMember&gt; cm = new list&lt;CampaignMember&gt;();

			for(Lead L : Trigger.new) {

					String cname = L.leadsource;

					// Added for AppExchange Partners that get leads via AppExchange where Salesforce added the &quot;dup-&quot; term to signify a duplicate
					String replaceText2 = &#039;dup-&#039;;
					cname = cname.replace(replaceText2,&#039;&#039;);

					List &lt;Campaign&gt; c = [select id, name from Campaign where name = :cname limit 1];

					if(!c.isEmpty()){
						CampaignMember cml = new CampaignMember();
						cml.campaignid = c[0].id;
						cml.leadid = l.id;
						cm.add(cml);
					}
			}

			if(!cm.isEmpty()){
				insert cm;
			}
		}

	} catch(Exception e) {
		system.debug (&#039;error: &#039; + e.getMessage() );
	}
}
</pre>
<p><strong>Bulkified Trigger</strong><br />
And now a corrected version to be bulkified.</p>
<pre class="syntax-highlight:java">
trigger Create_CampaignMember_For_New_Leads on Lead (after insert) {

	/*
    * Loop through all leads and collect the necessary lists
    */
	list&lt;Lead&gt; theLeads = new list&lt;Lead&gt;(); // List containing each Lead being processed
	list&lt;String&gt; cNames = new list&lt;String&gt;(); // List of Campaign Names
	map&lt;String, String&gt; map_lSource_to_cName = new map&lt;String, String&gt;(); // Mapping Lead Sources to Campaign Names. We have this because we are cleaning up Lead Sources in some cases.
	String wrkText = &#039;&#039;; // Temporary, working variable
	String replaceText = &#039;dup-&#039;; // Text to replace. This is included for ISV partners who want to remove the &quot;-dup&quot; string that is included for duplicate AppExchange Lead Submissions  

		for(Lead l:trigger.new) {
			theLeads.add(l); // add lead to the main lead list
			if (l.leadsource != null) {
				wrkText = l.leadsource;
				wrkText = wrkText.replace(replaceText,&#039;&#039;);
				cNames.add(wrkText); // add to list of Campaign Names
				map_lSource_to_cName.put(l.leadsource,wrkText); // add to map of Lead Sources to Campaign Names
			}
		}

	/*
	* Create a map containing an association of Campaign Names to Campaign IDs
	*/
	list&lt;Campaign&gt; theCampaigns = [SELECT Id, Name FROM Campaign WHERE Name IN :cNames]; // Campaign sObjects we are dealing with
	map&lt;String, ID&gt; map_cName_to_cID = new map&lt;String, ID&gt;(); // Mapping Campaign Names to Campaign IDs

		for (Campaign c:theCampaigns) {
			map_cName_to_cID.put(c.Name,c.Id);
		}

	/*
	* Loop through the main list of Leads
	*/
	list &lt;CampaignMember&gt; theCampaignMembers = new list&lt;CampaignMember&gt;(); // List containing Campaign Member records to be inserted

	for (Lead l:theLeads) {
		if(map_cName_to_cID.get(map_lSource_to_cName.get(l.leadsource)) != null) {
			CampaignMember cml = new CampaignMember();
			cml.leadid = l.id;
			cml.campaignid = map_cName_to_cID.get(map_lSource_to_cName.get(l.leadsource));
			theCampaignMembers.add(cml);
		}

	}

	/*
	* Insert the list of Campaign Members
	*/
	if(!theCampaignMembers.isEmpty()){
		insert theCampaignMembers;
	}

}
</pre>
<p><strong>Updated Test Class (100% code coverage)</strong><br />
I updated the test class too to make it cover 100% of the code.</p>
<pre class="syntax-highlight:java">
public class Create_CampaignMember_For_New_Leads {

	static testMethod void Create_CampaignMember_For_New_Leads() {

		// Create a Campaign to be matched on
		Campaign C1 = new Campaign();
		C1.Name = &#039;Matching Campaign&#039;;
		insert C1;

		// Create a Lead with a Lead Source matching a Campaign
		Lead L1 = new Lead();
		L1.lastname = &#039;Create_CampaignMember_For_New_Leads&#039;;
		L1.firstname = &#039;Test For&#039;;
		L1.company = &#039;Company ABC&#039;;
		L1.leadsource = &#039;Matching Campaign&#039;;

		insert L1;
		String holder = L1.id;

		List &lt;CampaignMember&gt; cm = [select id from CampaignMember where leadid = :holder limit 1];
		system.AssertEquals(1,cm.size());

		// Create a Lead without a Lead Source matching a Campaign
		Lead L2 = new Lead();
		L2.lastname = &#039;Create_CampaignMember_For_New_Leads&#039;;
		L2.firstname = &#039;Test For&#039;;
		L2.company = &#039;Company ABC&#039;;
		L2.leadsource = &#039;No Matching Campaign&#039;;

		insert L2;

		String holder2 = L2.id;

		List &lt;CampaignMember&gt; cm2 = [select id from CampaignMember where leadid = :holder2 limit 1];
		system.AssertEquals(0,cm2.size());

	}

}
</pre>
<p>Feel free to make additional recommendations on this code.  I updated the <a href="http://code.google.com/p/arrowpointe/" target=_blank>Arrowpointe Google Code Site</a> with this code too.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Make your Mass Email Activities more meaningful</title>
		<link>http://sfdc.arrowpointe.com/2008/07/25/make-your-mass-email-activities-more-meaningful/</link>
		<comments>http://sfdc.arrowpointe.com/2008/07/25/make-your-mass-email-activities-more-meaningful/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 20:05:48 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[Configuration]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=333</guid>
		<description><![CDATA[It had always bothered me that activities generated from Mass Emails only had a subject of &#8220;Mass Email:&#8221; and nothing in the body.  I couldn&#8217;t tell what I mass emailed to someone!
Deep inside the forums, I found the trick to get some meaning into those activities.  The best you can do is get the Subject [...]]]></description>
			<content:encoded><![CDATA[<p>It had always bothered me that activities generated from Mass Emails only had a subject of &#8220;Mass Email:&#8221; and nothing in the body.  I couldn&#8217;t tell what I mass emailed to someone!</p>
<p>Deep inside the forums, I found the trick to get some meaning into those activities.  The best you can do is get the Subject filled in, but that&#8217;s something.  The subject for a Mass Email = &#8220;Mass Email: <em>Email Template <span style="text-decoration: underline;">Description</span></em>&#8220;.  Giving your email templates a description is the only way to get a meaningful mass email activity.  The Description is an often overlooked field on Email Template because it&#8217;s not required, so go make sure you have it filled in.</p>
<p><img class="alignnone size-full wp-image-334" title="email-templates-for-mass-email" src="http://sfdc.arrowpointe.com/wp-content/images/email-templates-for-mass-email.png" alt="" width="500" height="79" /></p>
<p>Once you do this, the next Mass Email you send can start having some meaning.</p>
<p><img class="alignnone size-full wp-image-335" title="mass-email-activities" src="http://sfdc.arrowpointe.com/wp-content/images/mass-email-activities.png" alt="" width="500" height="108" /></p>
<p>I created <a href="http://ideas.salesforce.com/article/show/10090971/Generate_Meaningful_Mass_Email_Activities" target="_blank">an idea on Idea Exchange</a> for what I think a better design would be.  Vote on it and comment there to improve the recommendation.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/07/25/make-your-mass-email-activities-more-meaningful/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting Standard Object Meta Data into the Force.com IDE</title>
		<link>http://sfdc.arrowpointe.com/2008/06/26/getting-standard-object-meta-data-into-the-forcecom-ide/</link>
		<comments>http://sfdc.arrowpointe.com/2008/06/26/getting-standard-object-meta-data-into-the-forcecom-ide/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 20:03:00 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[API]]></category>

		<category><![CDATA[Configuration]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=315</guid>
		<description><![CDATA[Salesforce on Rails has an interesting post on how you can get the meta data for standard objects into the Force.com IDE for easy manipulation of its configuration via the Meta Data API capabilities built into the IDE.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://salesforceonrails.com/" target="_blank">Salesforce on Rails</a> has an <a href="http://salesforceonrails.com/2008/custom-fields-on-standard-objects-in-the-force-com-ide" target="_blank">interesting post</a> on how you can get the meta data for standard objects into the Force.com IDE for easy manipulation of its configuration via the Meta Data API capabilities built into the IDE.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/06/26/getting-standard-object-meta-data-into-the-forcecom-ide/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Best Thing about the Salesforce-Google Toolkit</title>
		<link>http://sfdc.arrowpointe.com/2008/06/25/best-thing-about-the-salesforce-google-toolkit/</link>
		<comments>http://sfdc.arrowpointe.com/2008/06/25/best-thing-about-the-salesforce-google-toolkit/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 01:14:13 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[APEX Code]]></category>

		<category><![CDATA[Google Apps]]></category>

		<category><![CDATA[News]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[The Community]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=314</guid>
		<description><![CDATA[As you probably know, Salesforce announced the Google Data API Toolkit on Monday.  Per the site,
The new Force.com Toolkit for Google Data APIs provides a free and open-source set of tools and services that developers can use to take advantage of Google Data APIs from within Force.com.
The end result for developers is a set of [...]]]></description>
			<content:encoded><![CDATA[<p>As you probably know, Salesforce announced the <a href="http://wiki.apexdevnet.com/index.php/Google_Data_API_Toolkit" target="_blank">Google Data API Toolkit</a> on Monday.  Per the site,</p>
<blockquote><p>The new Force.com Toolkit for Google Data APIs provides a free and open-source set of tools and services that developers can use to take advantage of Google Data APIs from within Force.com.</p></blockquote>
<p>The end result for developers is a set of classes, written by Salesforce, that allow you to easily communicate with Google services.  For example, suppose you want to create an entry in Google Calendar, the following code does it.</p>
<pre class="syntax-highlight:java">
GoogleData.Calendar cal = service.getCalendarByTitle(&#039;MyCalendar&#039;);
event newEvent = new Event(
subject = &#039;Tennis with Beth&#039;,
description = &#039;Meet for a quick lesson.&#039;,
ActivityDateTime = system.now(),
DurationInMinutes = 60);
</pre>
<p>That is actually just 2 lines of code (line #2 was broken into 5 lines for easier reading).  The reason you can do this in 2 lines is because of the toolkit.  The toolkit does the &#8220;heavy lifting&#8221; for you to communicate with Google.</p>
<p>From a developer standpoint, the <span style="text-decoration: underline;">best thing about this</span> is that, to do this, there is no dependency on changes to the Salesforce platform.  The Google Toolkit was created by the Developer Marketing Team at Salesforce, not the folks building the platform.  Apex Code is already part of the platform.  The toolkit uses what Apex Code already offers.   What you get with the toolkit is a set of pre-written Apex classes that do the heavy lifting for you on talking to Google.  Much like the Salesforce Java/PHP/.NET/Ajax/Perl toolkits do the heavy lifting of talking to the SOAP API for you on those programming platforms.</p>
<p>There is no reason that the developer community cannot create similar toolkits.  I am sure Salesforce has some more up their sleeve and did the community a service by building some foundational ones for us to use as working/useful examples.</p>
<p>This is open source at work.  To make an analogy&#8230; one thing I love about PHP is that these types of toolkits are prevalent and have made my life much easier. For example, when I wanted to build <a href="http://www.salesforce.com/appexchange/detail_overview.jsp?NavCode__c=&amp;id=a0330000001D8YnAAK" target="_blank">Auto vCard</a>, I Googled for PHP classes that created files in the vCard spec.  I found many and chose 1.  Similarly with the <a href="http://sfdc.arrowpointe.com/2007/05/24/fight-web-to-lead-spam-w-akismet/" target="_blank">Web to Lead Spam Check</a> I built.  I chose <a href="http://www.akismet.com" target="_blank">Akismet</a> as the spam checking service because I was familiar with it and trusted it and I found a <a href="http://www.achingbrain.net/stuff/php/akismet" target="_blank">PHP5 toolkit</a> that took care of the hard part of communicating with Akismet from PHP.  Same thing with my old <a href="http://www.arrowpointe.com/products/salesforce-google-maps/" target="_blank">Google Maps mashup.</a> There are PHP classes that do the hard part of talking to Google Maps.  Having these classes at my disposal gave me the ability to focus on adding the business value of tying functionality into a Salesforce-related use case.  If these PHP classes didn&#8217;t already exist, I never would have created <span style="text-decoration: underline;">any</span> those apps.</p>
<p>If you are a developer looking to create something similar to what Salesforce did, I suggest you:</p>
<ul>
<li>Visit <a href="http://www.programmableweb.com" target="_blank">Programmable Web</a> to identify useful services that could be connected to and learn about their APIs</li>
<li>Build your class(es) (Look at the <a href="http://code.google.com/p/apex-google-data/source/browse/trunk/google_data_toolkit/src/unpackaged/classes/XMLDom.cls" target="_blank">XMLDom</a> class that&#8217;s part of the Google toolkit to handle the complicated XML parsing you might need to do)</li>
<li>Publish it <span style="text-decoration: underline;">open source</span> and let the community react/improve it</li>
<li>Offer up some example code for how the class can be used to help people implement a use case of it.</li>
<li>Become a star</li>
</ul>
<p>Some services that I think are ripe for developers to concentrate on (that are very applicable to businesses):</p>
<ul>
<li>Google Checkout</li>
<li>PayPal</li>
<li>Authorize.net</li>
<li>Freshbooks</li>
<li>Google (Apps) Mail</li>
<li>Google Charts (with tie into Visual Force)</li>
<li>Blog Services</li>
<li>UPS</li>
<li>FedEx</li>
<li>Google Search</li>
<li>Facebook</li>
<li>LinkedIn</li>
<li>Google Open Social</li>
</ul>
<p>There are countless others.  Get cracking!</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/06/25/best-thing-about-the-salesforce-google-toolkit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Auto-Create Campaign Members for New Leads</title>
		<link>http://sfdc.arrowpointe.com/2008/06/19/auto-create-campaign-members-for-new-leads/</link>
		<comments>http://sfdc.arrowpointe.com/2008/06/19/auto-create-campaign-members-for-new-leads/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 01:23:20 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[APEX Code]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=311</guid>
		<description><![CDATA[After you finish reading this, check out a newer post that &#8220;bulkifies&#8221; the trigger.
I created a simple &#38; very useful Apex script that will auto-create Campaign Members for me when new leads are entered manually or via Web to Lead IF the Lead Source value matches the Name of a Campaign record I have in [...]]]></description>
			<content:encoded><![CDATA[<p><small>After you finish reading this, check out a <a href="http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/">newer post</a> that &#8220;bulkifies&#8221; the trigger.</small></p>
<p>I created a simple &amp; very useful Apex script that will auto-create Campaign Members for me when new leads are entered manually or via Web to Lead <strong>IF</strong> the Lead Source value matches the Name of a Campaign record I have in my Salesforce database.  If there is no match, then the code finishes.</p>
<p>This is useful for me because I get Leads sent to me everytime someone Test Drives, Installs or clicks Contact Me on an <a href="http://www.salesforce.com/appexchange/search.jsp?searchExchangeId=a0130000006P6IoAAK&amp;search=arrowpointe&amp;category=ALLAPPS" target="_blank">Arrowpointe AppExchange product</a>.  I will typically get duplicates in my org, which I go about merging.  If I don&#8217;t have Campaign Member records, I lose sight of all the activity someone did on AppExchange across my apps!  With Campaign Members populated, I can have a record of someone test driving <a href="http://www.salesforce.com/appexchange/detail_overview.jsp?NavCode__c=&amp;id=a0330000001D8YnAAK" target="_blank">Auto vCard</a> and then installing it, then test driving <a href="http://www.salesforce.com/appexchange/detail_overview.jsp?NavCode__c=&amp;id=a0330000001H2muAAC" target="_blank">User Adoption Dashboard</a> and then installing it and then test driving <a href="http://www.arrowpointe.com/getmaps" target="_blank">Arrowpointe Maps</a> and so on.  Also, using Campaign Members, I am essentially compiling an easily accessible list of people who have performed certain actions on my AppExchange apps.</p>
<p>Up until now, I was manually creating Campaign Members and then merging my Leads.  However, now I let Salesforce take care of the tedious Campaign Member creation (I still do the merging).</p>
<p>The code is simple and is officially living on the <a href="http://code.google.com/p/arrowpointe/">Arrowpointe Google Code site</a>.  The code isn&#8217;t likely to change anytime soon, so I am posting a working copy here for you.  This is a useful script to have in your quiver in case you need it.  The nice thing is that the trigger only takes effect when there is a match.  Thus, in order to get it working for a specific Lead Source, all you need to do is create a Campaign with a matching name.  Voila!</p>
<p><strong>Trigger</strong></p>
<pre class="syntax-highlight:java">
trigger Create_CampaignMember_For_New_Leads on Lead (after insert) {

	try {	

		if (Trigger.new.size() == 1) {

			List &lt;CampaignMember&gt; cm = new list&lt;CampaignMember&gt;();

			for(Lead L : Trigger.new) {

					String cname = L.leadsource;

					// Added for AppExchange Partners that get leads via AppExchange where Salesforce added the &quot;dup-&quot; term to signify a duplicate
					String replaceText2 = &#039;dup-&#039;;
					cname = cname.replace(replaceText2,&#039;&#039;);

					List &lt;Campaign&gt; c = [select id, name from Campaign where name = :cname limit 1];

					if(!c.isEmpty()){
						CampaignMember cml = new CampaignMember();
						cml.campaignid = c[0].id;
						cml.leadid = l.id;
						cm.add(cml);
					}
			}

			if(!cm.isEmpty()){
				insert cm;
			}
		}

	} catch(Exception e) {
		system.debug (&#039;error: &#039; + e.getMessage() );
	}
}
</pre>
<p><strong>Test Class</strong></p>
<pre class="syntax-highlight:java">
public class Create_CampaignMember_For_New_Leads {

	static testMethod void Create_CampaignMember_For_New_Leads() {

			List &lt;Lead&gt; Leads;

			// Create a Lead with a Lead Source matching a Campaign
			Lead L1 = new Lead();
			L1.lastname = &#039;Create_CampaignMember_For_New_Leads&#039;;
			L1.firstname = &#039;Test For&#039;;
			L1.company = &#039;Company Name&#039;;
			L1.leadsource = &#039;Web&#039;; // Make sure you have an active Campaign with this name

			insert L1;
			String holder = L1.id;

			List &lt;CampaignMember&gt; cm = [select id from CampaignMember where leadid = :holder limit 1];
			system.AssertEquals(1,cm.size());

			// Create a Lead without a Lead Source matching a Campaign
			Lead L2 = new Lead();
			L2.lastname = &#039;Create_CampaignMember_For_New_Leads&#039;;
			L2.firstname = &#039;Test For&#039;;
			L2.company = &#039;Company Name&#039;;
			L2.leadsource = &#039;No Matching Campaign&#039;; // Make sure you DON&#039;T have an active Campaign with this name 

			insert L2;

			String holder2 = L2.id;

			List &lt;CampaignMember&gt; cm2 = [select id from CampaignMember where leadid = :holder2 limit 1];
			system.AssertEquals(0,cm2.size());

	}
}
</pre>
<p>Let me know what you think, if I am doing anything inefficiently and other suggestions you might have.  This is my first foray into Apex Code, so I had to start simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/06/19/auto-create-campaign-members-for-new-leads/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Do you backup your Salesforce data?</title>
		<link>http://sfdc.arrowpointe.com/2008/04/28/do-you-backup-your-salesforce-data/</link>
		<comments>http://sfdc.arrowpointe.com/2008/04/28/do-you-backup-your-salesforce-data/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 18:23:03 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=303</guid>
		<description><![CDATA[No matter where you store your data, it is always good practice to maintain backups.  After all, it is your data and you need to be responsible for it, although we trust 3rd parties to keep it safe and backed up for us too.
When it comes to Salesforce, are you maintaining backups?  If [...]]]></description>
			<content:encoded><![CDATA[<p>No matter where you store your data, it is always good practice to maintain backups.  After all, it is your data and you need to be responsible for it, although we trust 3rd parties to keep it safe and backed up for us too.</p>
<p>When it comes to Salesforce, are you maintaining backups?  If so, how?  Please comment and enlighten the community on some good options you&#8217;ve deployed.  Some that spring to mind for me are:</p>
<ul>
<li><strong>Weekly Data Export </strong>- Inside Salesforce, Enterprise and Unlimited Edition customers (for a fee, Professional Edition can do this) can request a weekly export of their data.  The result is a ZIP of CSV files containing the raw data for each Salesforce object.</li>
<li><strong>Custom Script</strong> - Write custom code to access Salesforce via the API and grab all the data into your own database.  <a href="http://www.mikesimonds.com/" target="_blank">Mike Simonds</a> has some scripts to help get you started if you use PHP.</li>
<li><strong>AppExchange Application </strong>- Use an AppExchange application to do the dirty work to automate this process.  Visit the <a href="http://www.appexchange.com" target="_blank">AppExchange</a> to read about the various solutions.
<ul>
<li>Sesame Software - I find this tool very easy to use and can get your Salesforce data into Oracle, MySQL, SQL Server, etc. in a hurry.</li>
<li>CRM Fusion - They have a feature to backup your data directly into MS Access.</li>
<li>Other Data Loading/Moving Tool - Pervasive, Informatica, Bluewolf, Apatar and others have solutions to move data from place to place with a connector to Salesforce built in.</li>
</ul>
</li>
<li><strong>Do Nothing </strong>- Let Salesforce take care of it.  They have a proven track record of keeping your data from disaster.</li>
<li>Something else?</li>
</ul>
<p>I wish I personally had a better answer, but I am currently using the &#8220;Do Nothing&#8221; approach and occasionally make backups to MS Access using Demand Tools &#8220;just in case&#8221;.</p>
<p>How about you?  Experiences, recommendations and general thoughts are welcome in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/04/28/do-you-backup-your-salesforce-data/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Derive a Rating using Formulas</title>
		<link>http://sfdc.arrowpointe.com/2008/03/27/derive-a-rating-using-formulas/</link>
		<comments>http://sfdc.arrowpointe.com/2008/03/27/derive-a-rating-using-formulas/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 19:49:24 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[Configuration]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/2008/03/27/derive-a-rating-using-formulas/</guid>
		<description><![CDATA[On a recent project, I was helping my client prioritize their lead data. They were having trouble with the default Rating field in Salesforce because 1) it required a user to populate the record and 2) the rating should change with the passing of time.
I came up with a formula that takes the Lead Status [...]]]></description>
			<content:encoded><![CDATA[<p>On a recent project, I was helping my client prioritize their lead data. They were having trouble with the default Rating field in Salesforce because 1) it required a user to populate the record and 2) the rating should change with the passing of time.</p>
<p>I came up with a formula that takes the Lead Status and Expected Close Date (a custom field) into account in order to derive a Rating value on a Lead. This client happens to use Leads for their entire sales cycle and converts Leads once they are sold, but this concept would apply to equally to Opportunities as well.</p>
<h6>Requirements</h6>
<p>The simplified requirements are to derive a Rating value as follows:</p>
<table style="font-size: 80%; width: 500px; text-align: center" cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr style="font-weight: bold; color: #ffffff; background-color: #000000">
<td style="text-align: left">Lead Status / Days to Close</td>
<td>0 to 30 days</td>
<td>31 to 60 days</td>
<td>61 to 90 days</td>
<td>over 90 days</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">New</td>
<td>New</td>
<td>New</td>
<td>New</td>
<td>New</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Contacted</td>
<td>Warm</td>
<td>Warm</td>
<td>Cold</td>
<td>Cold</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Interested</td>
<td>Warm</td>
<td>Warm</td>
<td>Warm</td>
<td>Cold</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Presentation</td>
<td>Hot</td>
<td>Warm</td>
<td>Warm</td>
<td>Cold</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Sent I/O</td>
<td>Hot</td>
<td>Hot</td>
<td>Hot</td>
<td>Warm</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Sold</td>
<td>Won</td>
<td>Won</td>
<td>Won</td>
<td>Won</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Lost - No Contact</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Lost - No Budget</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
</tr>
<tr>
<td style="background-color: #cccccc; text-align: left">Lost - Not Interested</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
<td>Lost</td>
</tr>
</tbody>
</table>
<p>They plan to manage their pipeline closely using the derived Rating field. They want the Rating to get &quot;better&quot; as time passes, so that they can reinforce the use of the Expected Close Date field. For example, if there is a Lead in Presentation status and it gets forgotten by Sales, that lead&#8217;s rating will eventually get to &quot;Hot&quot; as the Expected Close Date approaches or is passed. Management will be asking about that Lead and it will either be accurate or the Expected Close Date will be updated to better reflect reality. Over time, they will really be able to trust the Expected Close Date field, which is a new field for them.</p>
<h6>Solution</h6>
<p>To accomplish this, I did the following:</p>
<ol>
<li>Added a custom field on Leads called <strong>Expected Close Date</strong>. This would be filled out by the end-user and acts like the Close Date does on an Opportunity. </li>
<li>Added a custom formula field called <strong>Days to Close</strong> that calculates how many days away the Expected Close Date is. The formula is as follows:
<p style="font-size: 1.1em; margin: 10px 20px; font-family: monospace">Expected_Close_Date__c - TODAY()</p>
<p>This field was added to the Page Layout because it is pretty useful in and of itself. Also, the client is on Professional Edition, so we wanted this field available in reports and that&#8217;s how you make it visible.</p>
</li>
<li>Added a custom formula field called <strong>Rating (derived)</strong> that calculates a rating value using the requirements from the table above. I use this formula approach (using the CASE function) whenever I am doing some kind of matrixed formula result.
<div style="font-size: 1.1em; margin: 10px 20px; font-family: monospace">CASE(1,
<p>IF(ISPICKVAL( Status ,&quot;New&quot;), 1, 0),&quot;New&quot;,</p>
<p>IF(AND(ISPICKVAL( Status ,&quot;Contacted&quot;), Days_to_Close__c &lt;= 60), 1, 0),&quot;Warm&quot;,         <br />IF(AND(ISPICKVAL( Status ,&quot;Contacted&quot;), Days_to_Close__c &gt; 60), 1, 0),&quot;Cold&quot;,</p>
<p>IF(AND(ISPICKVAL( Status ,&quot;Interested&quot;), Days_to_Close__c &lt;= 90), 1, 0),&quot;Warm&quot;,         <br />IF(AND(ISPICKVAL( Status ,&quot;Interested&quot;), Days_to_Close__c &gt; 90), 1, 0),&quot;Cold&quot;,</p>
<p>IF(AND(ISPICKVAL( Status ,&quot;Presentation&quot;), Days_to_Close__c &lt;= 30), 1, 0),&quot;Hot&quot;,         <br />IF(AND(ISPICKVAL( Status ,&quot;Presentation&quot;), Days_to_Close__c &lt;= 90), 1, 0),&quot;Warm&quot;,          <br />IF(AND(ISPICKVAL( Status ,&quot;Presentation&quot;), Days_to_Close__c &gt; 90), 1, 0),&quot;Cold&quot;,</p>
<p>IF(AND(ISPICKVAL( Status ,&quot;Sent I/O&quot;), Days_to_Close__c &lt;= 90), 1, 0),&quot;Hot&quot;,         <br />IF(AND(ISPICKVAL( Status ,&quot;Sent I/O&quot;), Days_to_Close__c &gt; 90), 1, 0),&quot;Warm&quot;,</p>
<p>IF(ISPICKVAL( Status ,&quot;Sold&quot;), 1, 0),&quot;Won&quot;,</p>
<p>IF(ISPICKVAL( Status ,&quot;Lost - No Contact&quot;), 1, 0),&quot;Lost&quot;,         <br />IF(ISPICKVAL( Status ,&quot;Lost - No Budget&quot;), 1, 0),&quot;Lost&quot;,          <br />IF(ISPICKVAL( Status ,&quot;Lost - Not Interested&quot;), 1, 0),&quot;Lost&quot;,          <br />&quot;&quot;)          </p>
</p></div>
</li>
<li>The Lead Views and Reports we made for reps are driven by this derived field. By doing this, they have 1 simple value to prioritize on. Also, as new Lead Statuses emerge or if we re-define what &quot;Hot&quot; means, we only need to modify the formula. When we do, all the reports and views automatically pick it up since they are not hardcoding filters on the Lead Status of Expected Close Date fields.     </li>
</ol>
<p>Does anyone else use an approach like this? Any suggestions to make it better?</p>
<p>Depending upon complexity, it is possible to hit formula size limits. Especially considering the need to use the ISPICKVAL function for the Lead Status. <a href="http://ideas.salesforce.com/article/show/43022/The_ability_to_use_a_picklist_value_in_a_formula_field_without_ISPICKVAL" target="_blank">Vote on this idea</a> to fix the ISPICKVAL issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/03/27/derive-a-rating-using-formulas/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Opportunity Roll-Up Summary Recommendations</title>
		<link>http://sfdc.arrowpointe.com/2008/03/07/opportunity-roll-up-summary-recommendations/</link>
		<comments>http://sfdc.arrowpointe.com/2008/03/07/opportunity-roll-up-summary-recommendations/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 07:13:12 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[Arrowpointe Maps]]></category>

		<category><![CDATA[Arrowpointe Products]]></category>

		<category><![CDATA[Configuration]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/2008/03/07/opportunity-roll-up-summary-recommendations/</guid>
		<description><![CDATA[Salesforce released Opportunity Roll-Up Summary fields on the Account object in the Spring 08 release.  This is a pretty useful feature and below are some recommendations to help you get started using them.
One of the major benefits of this feature is that you now get quick answers on the Accounts you are selling to [...]]]></description>
			<content:encoded><![CDATA[<p>Salesforce released <a href="http://blogs.salesforce.com/features/2008/01/opportunity-rol.html" target=_blank>Opportunity Roll-Up Summary</a> fields on the Account object in the Spring 08 release.  This is a pretty useful feature and below are some recommendations to help you get started using them.</p>
<p>One of the major benefits of this feature is that you now get quick answers on the Accounts you are selling to without having to run an Opportunity report and get multiple records for the same Account.  If you sell to a customer multiple times throughout the year, that customer will be represented once in an Account report, but will be represented multiple times (once for each sale) in an Opportunity report.</p>
<h6>Create the Fields</h6>
<p>To get started, create a new Account field and choose the <strong>Roll-Up Summary</strong> option and click Next.</p>
<p><img src="http://sfdc.arrowpointe.com/wp-content/images/rollup_summary_newfield.jpg" alt="rollup_summary_newfield.jpg" title="rollup_summary_newfield.jpg" width="450" height="184" border="0" /></p>
<p>Next, give it a name.  I&#8217;d like to recommend a <u>naming convention</u> because you will probably create multiple of these.  My personal naming convention is used in the example fields below.  For the API name, you should also use a naming convention.  This will help keep these fields together when viewed in Eclipse or Explorer.</p>
<p>After clicking Next, your options are to COUNT, SUM, MIN, MAX information from the Opportunity.  Below is a table with some ideas for fields you that might be useful:</p>
<table border="1" cellspacing="2" style="width: 90%;">
<tbody>
<tr>
<td><strong>Field Name</strong></td>
<td><strong>Rollup Type</strong></td>
<td><strong>Field to Aggregate</strong></td>
<td><strong>Filter Criteria</strong></td>
</tr>
<tr>
<td>$ Opportunities (Open)</td>
<td>SUM</td>
<td>Amount</td>
<td>Closed = False</td>
</tr>
<tr>
<td>$ Opportunities (Open - This Year)</td>
<td>SUM</td>
<td>Amount</td>
<td>1) Closed = False<br />2) Close Date = THIS YEAR <sup><a href="#fn1204872700206n" id="fn1204872700206" class="footnote">1</a></sup></td>
</tr>
<tr>
<td>$ Opportunities (Won)</td>
<td>SUM</td>
<td>Amount</td>
<td>Won = True</td>
</tr>
<tr>
<td>$ Opportunities (Lost)</td>
<td>SUM</td>
<td>Amount</td>
<td>1) Won = False<br />2) Closed = True</td>
</tr>
<tr>
<td># Opportunities (Open)</td>
<td>COUNT</td>
<td>N/A</td>
<td>Closed = False</td>
</tr>
<tr>
<td># Opportunities (Open - This Year)</td>
<td>COUNT</td>
<td>N/A</td>
<td>1) Closed = False<br />2) Close Date = THIS YEAR</td>
</tr>
<tr>
<td># Opportunities (Won)</td>
<td>COUNT</td>
<td>N/A</td>
<td>Won = True</td>
</tr>
<tr>
<td># Opportunities (Lost)</td>
<td>COUNT</td>
<td>N/A</td>
<td>1) Won = False<br />2) Closed=True</td>
</tr>
</tbody>
</table>
<h6>Using Formulas on the Rollups</h6>
<p>One really nice thing about these Rollup fields is that you can use their results in your regular formula fields.  Using the rollup fields I mentioned above, we can use formula fields on the account to create the fields such as:</p>
<ul>
<li>Win Rate (%) = # Opportunities (Won) / (# Opportunities (Won) + # Opportunities (Lost))</li>
<li>Avg Win Amount = $ Opportunities (Won) / # Opportunities (Won)</li>
</ul>
<h6>Using the Roll-Ups</h6>
<p>Now those rollup fields can come in handy in reporting to do things like:</p>
<ul>
<li>Filter for all sold-to Accounts:  $ Opportunities (Won) > 0</li>
<li>Filter for all Accounts with Open Opportunities:  # Opportunities (Open - This Year) > 0</li>
</ul>
<p>Another possiblity is in, say, <a href="http://www.arrowpointe.com/maps" target=_blank>an application that allows you to <strong>map your Salesforce.com data</strong></a>.  Adding the $ Opportunities (Won) field onto the query page makes generating a map of all sold-to accounts a breeze.</p>
<p><img src="http://sfdc.arrowpointe.com/wp-content/images/arrowpointemaps_AllWonAccounts.jpg" alt="arrowpointemaps_AllWonAccounts.jpg" title="arrowpointemaps_AllWonAccounts.jpg" width="557" height="245" border="0" /></p>
<p>What about you?  How are you using Roll-Up Summary fields?</p>
<p class="footnotes">
<p id="fn1204872700206n"><sup>1</sup> [<a href="#fn1204872700206">back</a>] - Other date filters include THIS QUARTER, THIS MONTH, LAST MONTH, NEXT YEAR, NEXT QUARTER, etc.  Refer to the Salesforce help for more.  These date filters are particularly useful for rollup summary fields.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/03/07/opportunity-roll-up-summary-recommendations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Developing Arrowpointe Maps (the tools)</title>
		<link>http://sfdc.arrowpointe.com/2008/02/26/developing-arrowpointe-maps-the-tools/</link>
		<comments>http://sfdc.arrowpointe.com/2008/02/26/developing-arrowpointe-maps-the-tools/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 20:47:29 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
		
		<category><![CDATA[Arrowpointe Maps]]></category>

		<category><![CDATA[Arrowpointe Products]]></category>

		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/2008/02/26/developing-arrowpointe-maps-the-tools/</guid>
		<description><![CDATA[It&#8217;s been a while since I blogged, so I thought I&#8217;d get back into it by talking a bit about the tools used to develop Arrowpointe Maps in the hopes that you might find this useful for your own development and that you might comment here about your tools of choice and what makes them [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I blogged, so I thought I&#8217;d get back into it by talking a bit about the tools used to develop <a href="http://www.arrowpointe.com/maps" target=_blank>Arrowpointe Maps</a> in the hopes that you might find this useful for your own development and that you might comment here about your tools of choice and what makes them great.</p>
<h6>The Stack</h6>
<p>Although you access the application via a Web Tab in Salesforce.com, Arrowpointe Maps is actually hosted with <a href="http://www.opsource.net" target=_blank>OpSource</a>, one of the 2 pre-certified Salesforce.com hosting providers, and is running on a LAMPS (<strong>L</strong>inux/<strong>A</strong>pache/<strong>M</strong>ySQL/<strong>P</strong>HP/<strong>S</strong>alesforce) stack.</p>
<p>Ideally, this entire stack will be replaced by Force.com.  Someday it might.  At this time, however, Force.com just isn&#8217;t ready to take on all of this and Apex Code, especially, doesn&#8217;t have the flexibility or community of something like PHP.  I look forward to improvements being made to all of the Force.com components and hopefully Arrowpointe Maps can eventually be a showcase application running 100% on the platform.</p>
<p>Another architecture I really like is Adobe&#8217;s Flex technology.  Both Salesforce &#038; MapQuest have really good Flex integration.  I really like this approach and you might start seeing some Flex output in future releases.</p>
<h6>Web Services</h6>
<p><a href="http://developer.salesforce.com" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/salesforcelogo.jpg" alt="salesforcelogo.jpg" title="salesforcelogo.jpg" width="210" height="63" border="0" style="float: left; margin: 0 5px 5px 0;" /></a>All the business data resides in the user&#8217;s <a href="http://www.salesforce.com" target=_blank>Salesforce.com</a> database.  We connect to Salesforce.com via the API to access configuration information as well as business data for mapping purposes.  The application leverages the end-user&#8217;s Salesforce.com session, so all authentication is piggy-backing off of the Salesforce.com security model, which is really nice.  Because Arrowpointe Maps is certified, we get a Client ID that gives us API access to Professional Edition orgs too.</p>
<p><a href="http://developer.mapquest.com" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/MapQuest_Logo_small.gif" alt="MapQuest_Logo_small.gif" title="MapQuest_Logo_small.gif" width="150" height="22" border="0" style="float: left; margin: 0 5px 5px 0;" /></a>We use the <a href="http://developer.mapquest.com" target=_blank>MapQuest JavaScript API (Tiled Maps)</a>.  MapQuest&#8217;s API is really well put together, is accurate and reliable.  I&#8217;ve been very pleased with it.  They are rolling out new functionality all the time and I do my best to incorporate the most useful pieces with each release.</p>
<p>I will be looking to incorporate more useful web services into the mix as the product expands.  <a href="http://www.programmableweb.com" target=_blank>Programmable Web</a> is the best resource I know for a comprehensive listing of web APIs.</p>
<h6>Development Frameworks</h6>
<p><a href="http://xajaxproject.org/" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/xajax_logo.gif" alt="xajax_logo.gif" title="xajax_logo.gif" width="72" height="62" border="0" style="float: left; margin: 0 5px 5px 0;" /></a><a href="http://xajaxproject.org/" target=_blank>xAjax</a> is an open source PHP library for building Web-based Ajax applications.  It makes it dead simple to perform an AJAX server call, do the heavy lifting in PHP and then return HTML and JavaScript to the page without an entire refresh.  It has allowed me to keep the bulk of the logic in the comfort and power of PHP and only using JavaScript where I need to.</p>
<p><a href="http://www.prototypejs.org/" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/prototype_logo.png" alt="prototype_logo.png" title="prototype_logo.png" width="75" height="34" border="0" style="float: left; margin: 0 5px 5px 0;"/></a><a href="http://www.prototypejs.org/" target=_blank>Prototype</a> is a JavaScript Framework that aims to ease development of dynamic web applications.  If you do any JavaScript development, this is a must have.  It provides many useful methods for working with the DOM and has been written to be cross-browser compatible.  It&#8217;s worth using if only for its $ function.</p>
<p><a href="http://developer.yahoo.com/yui" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/yahoo_logo.gif" alt="yahoo_logo.gif" title="yahoo_logo.gif" width="65" height="38" border="0" style="float: left; margin: 0 5px 5px 0;" /></a>The <a href="http://developer.yahoo.com/yui" target=_blank>Yahoo User Interface Library (YUI)</a> is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX.  I use it in a few random places in Arrowpointe Maps.  YUI is the most well documented user interface framework I have seen and it&#8217;s been taken up well in the development community.  I highly suggest it.</p>
<p>I am not using these JavaScript frameworks, but I came across them in my research and they have good reputations:</p>
<ul>
<li><a href="http://code.google.com/webtoolkit/" target=_blank>Google Web Toolkit</a></li>
<li><a href="http://script.aculo.us/" target=_blank>script.aculo.us</a></li>
<li><a href="http://dojotoolkit.org/" target=_blank>Dojo</a></li>
</ul>
<h6>Other Development Tools</h6>
<p><a href="http://www.eclipse.org" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/eclipse_logo.jpg" alt="eclipse_logo.jpg" title="eclipse_logo.jpg" width="75" height="49" border="0"  style="float: left; margin: 0 5px 5px 0;"/></a>Eclipse is an open source community whose projects are focused on building an open development platform comprised of extensible frameworks, tools and runtimes for building, deploying and managing software across the lifecycle.  It is my main PHP development environment and Salesforce also has their <a href="http://wiki.apexdevnet.com/index.php/Force.com_IDE" target=_blank>Force.com IDE</a> in Eclipse, which is useful.  There are a number of &#8220;projects&#8221; that I use in Eclipse, but some of the standouts are:</p>
<ul>
<li><a href="http://www.eclipse.org/webtools/" target=_blank>Web Tools Platform</a></li>
<li><a href="http://www.eclipse.org/pdt/" target=_blank>PHP Development Tools</a></li>
<li><a href="http://subclipse.tigris.org/" target=_blank>Subclipse</a>:  Plugin to support connectivity to a Subversion (SNV) code repository.</li>
<li><a href="http://www.eclipse.org/mylyn/" target=_blank>Mylyn</a>:  Provides task management functionality in Eclipse.  I utilize the <a href="http://trac.edgewall.org/" target=_blank>Trac </a>connector to connect to my Trac system that I use to manage my defect &#038; enhancement request tracking.</li>
</ul>
<p><a href="http://www.devguard.com/" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/devguard_logo.jpg" alt="devguard_logo.jpg" title="devguard_logo.jpg" width="100" height="23" border="0" style="float: left; margin: 0 5px 5px 0;"/></a>I use <a href="http://www.devguard.com/" target=_blank>DevGuard</a> for professional SVN hosting.  It&#8217;s pretty cheap and provides good tools for managing my code in a secure place.  It also includes the Trac project management system that sits on top of SVN and it all integrates very well into Eclipse.  This services are similar to what <a href="http://code.google.com/hosting/" target=_blank>Google Code</a> provides, but it keeps the code private and is not open-source.</p>
<p><a href="http://www.appexchange.com" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/appexchange_logo.jpg" alt="appexchange_logo.jpg" title="appexchange_logo.jpg" width="110" height="24" border="0" style="float: left; margin: 0 5px 5px 0;" /></a><a href="http://www.arrowpointe.com/getmaps" target=_blank>Arrowpointe Maps</a> is distributed via the AppExchange.  The AppExchange makes it simple for any Salesforce prospect, customer or developer to download the application for free, no questions asked.  Now they have what they need to connect to me and this allows me the flexibility to enable/disable access to the application as necessary.</p>
<p><a href="http://www.getfirebug.com" target=_blank><img src="http://sfdc.arrowpointe.com/wp-content/images/firebug_logo.jpg" alt="firebug_logo.jpg" title="firebug_logo.jpg" width="100" height="34" border="0" style="float: left; margin: 0 5px 5px 0;"/></a><a href="http://www.getfirebug.com" target=_blank>Firebug</a> integrates with Firefox to let you edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.  I use it every single day for a multitude of reasons.  I highly recommend it.</p>
<h6>References</h6>
<ul>
<li><a href="http://developer.mapquest.com" target=_blank>MapQuest&#8217;s API Reference and Forums</a>: I go here almost everyday.  They are migrating everything to the developer site I linked to.  Currently, most of their documentation is in their <a href="http://trc.mapquest.com" target=_blank>Technical Resource Center</a>.</li>
<li><a href="http://www.salesforce.com/us/developer/docs/api/index.htm" target=_blank>Salesforce&#8217;s API Reference</a>:  Used pretty regularly, especially as I delve into more obscure areas of the API and special use cases.</li>
<li><a href="http://wiki.apexdevnet.com/index.php/Members:Platform_Cookbook" target=_blank>Force.com Cookbook</a>:  I use this pretty rarely, but it has some really good examples in it, so I keep it handy.</li>
<li><a href="http://www.php.net/download-docs.php" target=_blank>PHP Manual</a>:  I downloaded the CHM file from this page and I use it multiple times every single day.  It&#8217;s the best resource for PHP information.  If you visit <a href="http://www.php.net/manual/en/" target=_blank>the same documentation online</a>, each page has other developers adding comments, so you get some rich information.</li>
<li><a href="http://www.w3schools.com/" target=_blank>W3Schools</a>: My one-stop shop for the official reference to HTML, JavaScript, the DOM and CSS.  I used it a bit to learn XML too.  I go here almost every day.</li>
<li><a href="http://www.prototypejs.org/api" target=_blank>Prototype Documentation</a>:  The API docs for this most useful JavaScript framework.</li>
<li><a href="http://developer.yahoo.com/yui/" target=_blank>YUI Documentation</a>: Yahoo has documented their Yahoo User Interface Library very well.</li>
<li><a href="http://www.google.com" target=_blank>Google</a>:  When at a loss, use Google to find examples of what you are trying to do.  I try and corroborate most of the examples I find from a few sources before applying it to my development.</li>
</ul>
<p>Some other, random tools I use that make my development/work life easier are:</p>
<ul>
<li><a href="http://www.techsmith.com" target=_blank>Snag-It</a>:  Taking screen captures and for light image editing.</li>
<li><a href="http://www.jungledisk.com" target=_blank>Jungle Disk</a>:  Mount Amazon&#8217;s S3 storage service as a drive and backup files to it.  It encrypts all the files stored there.</li>
<li><a href="http://www.ceruleanstudios.com/" target=_blank>Trillian</a>: multi-protocol instant messaging client.</li>
<li><a href="http://www.jingproject.com" target=_blank>Jing Project</a>: Create demonstration videos.  From the creators of Snag-It.</li>
</ul>
<p>What about you?  For developing applications (especially Salesforce-related ones) what tools are you using and recommend?</p>
]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2008/02/26/developing-arrowpointe-maps-the-tools/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
