<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atomfull.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="0.3">
  <title>Service and Support Blog</title>
  <link rel="alternate" type="text/html" href="http://blogs.salesforce.com/support/" />
  <id>tag:typepad.com,2003:weblog-483439</id>
  <link rel="service.post" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439" title="Service and Support Blog" />
  <modified>2008-11-26T23:04:59Z</modified>

  <generator url="http://www.typepad.com/">TypePad</generator>
  <info type="application/xhtml+xml">
  <div xmlns="http://www.w3.org/1999/xhtml">This is an Atom formatted XML site feed. It is intended to be viewed in a Newsreader or syndicated to another site. Please visit <a href="http://blogs.salesforce.com/support/">Service and Support Blog</a> for more info.</div>
  </info>
  <link rel="start" href="http://feeds.feedburner.com/typepad/Successforce/support" type="application/atom+xml" /><entry>
    <title>Email-to-Case Best Practices - Part 2: Things to Consider</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/466720175/email-to-case-1.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=58690220" title="Email-to-Case Best Practices - Part 2: Things to Consider" />
    <id>tag:typepad.com,2003:post-58690220</id>
    <issued>2008-11-26T15:04:59-08:00</issued>
    <modified>2008-11-26T23:11:41Z</modified>
    <created>2008-11-26T23:04:59Z</created>
    <summary>Guest blogger and Customer Service &amp; Support expert Peter Aubrey continues his thread on Email To Case. Today we feature part 2 of the 2-part series Email-to-Case Best Practices (see part 1 here): In order to identify the best way...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Guest blogger and Customer Service &amp;amp; Support expert &lt;strong&gt;Peter Aubrey&lt;/strong&gt; continues his thread on Email To Case.&amp;nbsp; Today we feature part 2 of the 2-part series Email-to-Case Best Practices (&lt;a href="http://blogs.salesforce.com/support/2008/11/email-to-case-b.html"&gt;see part 1 here&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;In order to identify the best way to setup email-to-case, it’s best to get a good understanding of exactly how the agent works.&amp;nbsp; You will also need to make a decision on the communication strategy with your customers.&amp;nbsp; Some customer service departments allow agents to give out direct email addresses or direct dial numbers.&amp;nbsp; Others only allow customers to contact the agents via central support email or telephone numbers.&amp;nbsp; Some companies have a mixture of both.&lt;/p&gt;

&lt;p&gt;Email-to-case will of course only take email from specific mailboxes that are dedicated to receiving email related to customer support issues.&amp;nbsp; If a customer sends an email directly to one of your agents then the agent can manually add those emails into Salesforce using Force.com Connect for Microsoft Outlook.&amp;nbsp; Salesforce can be configured so that agents can send emails with a variety of From addresses, thus ensuring, for example, that all responses from customers arrive at the central mailbox which email-to-case is polling.&lt;/p&gt;

&lt;p&gt;&lt;a onclick="window.open(this.href, '_blank', 'width=480,height=197,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/11/26/e2c1.png"&gt;&lt;img height="41" width="100" border="0" src="http://blogs.salesforce.com/support/images/2008/11/26/e2c1.png" title="E2c1" alt="E2c1" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt;
If the majority of the time you want your agents to send emails from a central support address, then each agent needs to modify his Email Settings by going to &lt;strong&gt;Setup: Personal Setup: Email: My Email Settings&lt;/strong&gt; and setting his &lt;strong&gt;Email Name&lt;/strong&gt; and &lt;strong&gt;Email Address&lt;/strong&gt; to the required central support address.&lt;/p&gt;

&lt;p&gt;When an agent sends an email from a Case, he gets the choice of sending the email from a number of email addresses.&amp;nbsp; Salesforce will default to the settings specified by the agent in his email preferences, however he also gets the choice of setting the from email address on the email to either &lt;a onclick="window.open(this.href, '_blank', 'width=456,height=126,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/11/26/e2c2_4.png"&gt;&lt;img height="27" width="100" border="0" src="http://blogs.salesforce.com/support/images/2008/11/26/e2c2_4.png" title="E2c2_4" alt="E2c2_4" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt;
their user record’s email address or any Routing Addresses that have been defined in your email-to-case settings.&lt;/p&gt;

&lt;p&gt;You can create a custom button that defaults the From address on the email page; for more on that, see this earlier blog entry: &lt;a href="http://blogs.salesforce.com/support/2008/07/the-quick-email.html"&gt;The Quick Email Button&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How are emails linked together to form a conversation?&lt;/strong&gt;&lt;br /&gt;When an agent sends an email from the Case page a special ID is created and added to the subject line of the mail so that a chain of mails can be uniquely identified as a conversation.&lt;/p&gt;

&lt;p&gt;However, this conversation ID is not created until an agent manually replies to the original email, an Auto-Response email does not include this unique ID.&amp;nbsp; Therefore if a customer responds to the Auto-Response mail then a new Case will be created since the unique ID is not included in the subject line of the email.&lt;/p&gt;

&lt;p&gt;This can be overcome in one of two ways.&lt;/p&gt;

&lt;p class="indented"&gt;&lt;strong&gt;1.&amp;nbsp; &lt;/strong&gt;&lt;strong&gt;Do Not Reply&lt;/strong&gt;&lt;br /&gt;Some of our customers set the sender’s name and email address to “Do Not Reply” addresses, along with a warning in the response saying not to reply to this automated email.&lt;/p&gt;

&lt;p class="indented"&gt;Note you could set up another email-to-case agent that monitors this email inbox to handle any emails are sent to the do not reply address.&lt;/p&gt;

&lt;p class="indented"&gt;&lt;strong&gt;2.&amp;nbsp; Create the ID using a Formula Field&lt;/strong&gt;&lt;br /&gt;The following formula field will calculate the thread ID, which is unique to each case.&amp;nbsp; This thread ID can then be added in to the Subject line or the body in your email template to make sure the ID is set even when an agent does not manually respond to the customer.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.salesforce.com/support/formula-for-the-emailtoca.html"&gt;Click here&lt;/a&gt; to see the formula that synthesizes the thread ID.&amp;nbsp; In the screenshot below, we've stored this formula in a custom field called &amp;quot;Case Communication ID&amp;quot; and added it to the subject line of our autoresponse template.&lt;/p&gt;

&lt;p class="indented"&gt;&lt;a onclick="window.open(this.href, '_blank', 'width=694,height=392,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/11/26/e2c3.png"&gt;&lt;img height="56" width="100" border="0" src="http://blogs.salesforce.com/support/images/2008/11/26/e2c3.png" title="E2c3" alt="E2c3" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt;
Note: if you use web-to-case then this technique can also be used to catch any immediate responses that customers may send to your support department, before an agent can respond.&lt;/p&gt;

&lt;p&gt;So in summary:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; Customer sends an email to support@yourcompany.com&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; Email-to-Case agent picks up the email and:&lt;/p&gt;
&lt;p class="indented"&gt;&lt;em&gt;a.&amp;nbsp; &amp;nbsp; Searches Salesforce to see if a Contact exists with an email that matches the from address of the inbound email.&lt;/em&gt;&lt;/p&gt;
&lt;p class="indented"&gt;&lt;em&gt;b.&amp;nbsp; &amp;nbsp; If a match cannot be found, or if more than one Contact is found, then the name and address contained in the email are stored in the Web Name and Web Email fields on the Case when it is created.&amp;nbsp; If a match is found then a Case is created and linked to the Contact and its corresponding Account.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; The appropriate Auto-Response Rule in Salesforce responds immediately with a message detailing Case Number, Subject, estimated response time, customer portal login link, suggested solutions, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; Assignment Rules evaluate the Case details and either places the Case into the correct queue or gives ownership to the correct individual.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; The Case Queue members or the individual to which the Case was assigned are notified via email that they have a Case to work on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt;&amp;nbsp; &amp;nbsp; Agent takes ownership of the Case and replies to the original email explaining that they will be working on their Case going forward.&amp;nbsp; Note that when the agent replies to the original email, the Open Task that was created is automatically closed.&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/11/email-to-case-1.html</feedburner:origLink></entry>
  <entry>
    <title>The Magic of the Gartner CSS Magic Quadrant Highlights Dreamforce</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/456548937/the-magic-of-th.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=58644986" title="The Magic of the Gartner CSS Magic Quadrant Highlights Dreamforce" />
    <id>tag:typepad.com,2003:post-58644986</id>
    <issued>2008-11-17T15:54:52-08:00</issued>
    <modified>2008-11-17T23:55:04Z</modified>
    <created>2008-11-17T23:54:52Z</created>
    <summary>Once again, Dreamforce was the highlight event of the season for Cloud computing and customer service and support, with over 34 speakers presenting their success in delivering game-changing solutions for customer service and support using salesforce.com. One of the most...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>News</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Once again, Dreamforce was the highlight event of the season for Cloud computing and customer service and support, with over 34 speakers presenting their success in delivering game-changing solutions for customer service and support using salesforce.com.&amp;nbsp; One of the most exciting events was the presence of Michael Maoz, Gartner analyst, and thought leader, whose vision and insight into the challenges and trends in customer service drew a standing room only crowd to the kick-off of the Customer Service and Support track.&lt;/p&gt;

&lt;p&gt;Read more about Michael’s experience at Dreamforce, as well as his ongoing dialog about the how to respond to the challenges you face every day at his blog: &lt;a href="http://blogs.gartner.com/michael_maoz/2008/11/04/dreamforce-demonstrates-salesforcecom-innovation-in-cloud-computing/"&gt;Dreamforce demonstrates salesforce.com innovation in cloud computing&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/11/the-magic-of-th.html</feedburner:origLink></entry>
  <entry>
    <title>Email-To-Case Best Practices -- Part 1: The Basics</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/452234272/email-to-case-b.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=58479850" title="Email-To-Case Best Practices -- Part 1: The Basics" />
    <id>tag:typepad.com,2003:post-58479850</id>
    <issued>2008-11-13T13:44:39-08:00</issued>
    <modified>2008-11-14T00:13:49Z</modified>
    <created>2008-11-13T21:44:39Z</created>
    <summary>People sometimes ask me whether Salesforce.com has an automated solution for turning emails into cases. The answer is yes! We've had one for years, and I'm not talking about Outlook Edition. Guest blogger and Salesforce.com Service &amp; Support expert Peter...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;People sometimes ask me whether Salesforce.com has an automated solution for turning emails into cases.&amp;nbsp; The answer is yes!&amp;nbsp; We've had one for years, and I'm not talking about Outlook Edition.&lt;/p&gt;

&lt;p&gt;Guest blogger and Salesforce.com Service &amp;amp; Support expert &lt;strong&gt;Peter Aubrey&lt;/strong&gt; has written up a primer on Email To Case and what it can do for you.&amp;nbsp; Here we have it:&lt;/p&gt;

&lt;div&gt;&lt;div&gt;&lt;div id="_com_1" class="msocomtxt" language="JavaScript" onmouseover="msoCommentShow('_anchor_1','_com_1')" onmouseout="msoCommentHide('_com_1')"&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Well, what a few days. Dreamforce was a fantastic experience where customers, partners and some of our most experienced employees shared ideas, best practices and generally showed how you can squeeze every dollar of ROI from your Salesforce implementation.&lt;/p&gt;

&lt;p&gt;One question that came up during the “Roundtable with the Service and Support Pros” session and one that comes up frequently in conversations I have with customers is what is email to case and how do I use it?&amp;nbsp; Well lets see if I can shed some light on this subject.&lt;br /&gt; &lt;strong&gt;&lt;br /&gt;What is email-to-case?&lt;/strong&gt;&lt;br /&gt;Email-to-case is a small Java application that can run on any server, desktop or laptop PC.&amp;nbsp; It is used to connect to an email mailbox on a periodic basis, process any email messages that are currently there by taking the details of the email and creating a Case in Salesforce.&amp;nbsp; Think of it as like any email client application such as Outlook, Lotus Notes or Thunderbird, it just doesn’t need anyone to operate it!&lt;/p&gt;

&lt;p&gt;If a Contact in Salesforce has the same email address as that in the from address in the email, then the email-to-case agent will link the Case to the Contact automatically.&lt;/p&gt;

&lt;p&gt;If a Contact cannot be found then the details of the sending email are stored in Web Name and Web Email fields on the Case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What email servers and mail protocols does email-to-case work with?&lt;/strong&gt;&lt;br /&gt;Email-to-case uses IMAP as the email protocol to communicate with your email server so it’s not a question of does email-to-case work with Microsoft Exchange, but does your mail server support the IMAP protocol.&lt;/p&gt;

&lt;p&gt;Exchange, Lotus Notes (Domino) and many other email servers are able to be configured to use the IMAP protocol, however this may not be enabled by default.&amp;nbsp; Also many web based email services such as Google support IMAP, which is what we’ll be using in our examples below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can email-to-case use IMAPS?&lt;/strong&gt;&lt;br /&gt;Yes. Simply state that the mail protocol as IMAPS and the port as 993 in the email2case.txt configuration file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I stop Spam?&lt;/strong&gt;&lt;br /&gt;Email-to-case does not provide any SPAM checking.&amp;nbsp; It is assumed that customers will provide SPAM filtering capabilities before they reach the email-to-case agent.&lt;br /&gt; &lt;strong&gt;&lt;br /&gt;Where do I download and setup email-to-case?&lt;/strong&gt;&lt;br /&gt;To download click here: &lt;a href="http://wiki.apexdevnet.com/index.php/Members:Email_To_Case"&gt;http://wiki.apexdevnet.com/index.php/Members:Email_To_Case&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;For instructions on how to setup see the Help files in Salesforce.com.&lt;br /&gt; &lt;strong&gt;&lt;br /&gt;Where do I get help and support?&lt;/strong&gt;&lt;br /&gt;1. Search for &amp;quot;Setting Up Email-to-Case&amp;quot; in Salesforce.com's help files.&lt;br /&gt;2. Search for &amp;quot;email-to-case&amp;quot; in the Community discussion forums found here &lt;a href="http://www.salesforce.com/community/community/"&gt;http://www.salesforce.com/community/community/&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://wiki.apexdevnet.com/index.php/Members:Email_To_Case"&gt;http://wiki.apexdevnet.com/index.php/Members:Email_To_Case&lt;/a&gt;&lt;br /&gt;4.&amp;nbsp; If all else fails, you can contact Salesforce.com Support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;br /&gt;Can I have more than one email-to-case agent running at the same time?&lt;/strong&gt;&lt;br /&gt;Yes.&amp;nbsp; You can have as many agents running at once as you'd like, monitoring at most 50 email inboxes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How about some sample settings?&lt;/strong&gt;&lt;br /&gt;Below are the settings I use for my email-to-case demonstrations.&amp;nbsp; There are two configuration files, email2case.txt and sfdcConfig.txt.&lt;/p&gt;

&lt;p&gt;email2case.txt&lt;/p&gt;

&lt;p&gt;&amp;lt;configFile&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;server1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;url&amp;gt;imap.gmail.com&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;protocol&amp;gt;imaps&amp;lt;/protocol&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;port&amp;gt;993&amp;lt;/port&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;userName&amp;gt;******@googlemail.com&amp;lt;/userName&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;password&amp;gt;******&amp;lt;/password&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;interval&amp;gt;1&amp;lt;/interval&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;inbox&amp;gt;inbox&amp;lt;/inbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;readbox&amp;gt;ReadMail&amp;lt;/readbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;errorbox&amp;gt;ErrorMail&amp;lt;/errorbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/server1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;server2&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;url&amp;gt;imap.gmail.com&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;protocol&amp;gt;imaps&amp;lt;/protocol&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;port&amp;gt;993&amp;lt;/port&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;userName&amp;gt;******donotreply@gmail.com&amp;lt;/userName&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;password&amp;gt;******&amp;lt;/password&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;interval&amp;gt;1&amp;lt;/interval&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;inbox&amp;gt;inbox&amp;lt;/inbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;readbox&amp;gt;ReadMail&amp;lt;/readbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;errorbox&amp;gt;ErrorMail&amp;lt;/errorbox&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/server2&amp;gt;&lt;br /&gt;&amp;lt;/configFile&amp;gt;&lt;/p&gt;

&lt;p&gt;sfdcConfig.txt&lt;/p&gt;

&lt;p&gt;&amp;lt;configFile&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;sfdcLogin&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;url&amp;gt;https://www.salesforce.com/services/Soap/u/9.0&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;userName&amp;gt;******&amp;lt;/userName&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;password&amp;gt;******&amp;lt;/password&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;loginRefresh&amp;gt;30&amp;lt;/loginRefresh&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;timeout&amp;gt;6000&amp;lt;/timeout&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/sfdcLogin&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;notify&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;lt;notifyEmail&amp;gt;******@gmail.com&amp;lt;/notifyEmail&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;from&amp;gt;******@gmail.com&amp;lt;/from&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;host&amp;gt;smtp.gmail.com&amp;lt;/host&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;port&amp;gt;465&amp;lt;/port&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;user&amp;gt;******@gmail.com&amp;lt;/user&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;password&amp;gt;******&amp;lt;/password&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;service&amp;gt;com.sforce.mail.SMTPNotification&amp;lt;/service&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/notify&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;attachments&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;largeAttachmentDirectory&amp;gt;C:\\largeattach\&amp;lt;/largeAttachmentDirectory&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;largeAttachmentURLPrefix&amp;gt;file:\\YOUR_COMPUTER_NAME\largeattach\&amp;lt;/largeAttachmentURLPrefix&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;largeAttachmentSize&amp;gt;5&amp;lt;/largeAttachmentSize&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/attachments&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;services&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;com.sforce.mail.EmailService&amp;gt;C:\\EmailAgent\\email2case.txt&amp;lt;/com.sforce.mail.EmailService&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/services&amp;gt;&lt;br /&gt;&amp;lt;/configFile&amp;gt;&lt;/p&gt;

&lt;p&gt;Thank you Peter!&amp;nbsp; Next week: Part 2: Things To Consider.&lt;/p&gt;

&lt;p&gt;-Marco Casalaina&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/11/email-to-case-b.html</feedburner:origLink></entry>
  <entry>
    <title>How To Stop People From Making Comments On Closed Cases</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/436207873/how-to-stop-peo.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=57743689" title="How To Stop People From Making Comments On Closed Cases" />
    <id>tag:typepad.com,2003:post-57743689</id>
    <issued>2008-10-29T13:14:44-07:00</issued>
    <modified>2008-10-29T20:15:09Z</modified>
    <created>2008-10-29T20:14:44Z</created>
    <summary>Sometimes customers ask me how they can make closed cases "uncommentable" – once those cases are closed, they don't want their reps to be able to make new comments on them. Traditionally the way to accomplish this would be to...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Sometimes customers ask me how they can make closed cases &amp;quot;uncommentable&amp;quot; – once those cases are closed, they don't want their reps to be able to make new comments on them.&lt;/p&gt;

&lt;p&gt;Traditionally the way to accomplish this would be to change the record type of closed cases and use a layout for that record type which hides the Case Comments related list.&amp;nbsp; This is not ideal, though, because it means that you can't read the comments either.&lt;/p&gt;

&lt;p&gt;Fortunately, with Workflow From Case Comments, there is now a better way.&lt;/p&gt;

&lt;p&gt;As I mentioned in my previous blog entry, Workflow From Case Comments is a &amp;quot;chaining&amp;quot; workflow, which means that when it edits the parent case, it kicks off the workflow anew on that case object.&amp;nbsp; We can use this to our advantage in solving this problem.&amp;nbsp; Here's how.&lt;/p&gt;

&lt;p&gt;1.&amp;nbsp; Define a checkbox-type custom field on Case called &amp;quot;No more comments.&amp;quot;&amp;nbsp; Do not add it to any of the Case page layouts.&lt;br /&gt;&lt;a href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/29/validation1.png" onclick="window.open(this.href, '_blank', 'width=800,height=744,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"&gt;&lt;img height="93" border="0" width="100" alt="Validation1" title="Validation1" src="http://blogs.salesforce.com/support/images/2008/10/29/validation1.png" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;2.&amp;nbsp; Make a validation rule which shows the error &amp;quot;You cannot add comments to a closed case&amp;quot; at the top of the page.&amp;nbsp; In the formula section put simply &amp;quot;No_more_comments__c =true&amp;quot; (see first screenshot, left).&lt;/p&gt;

&lt;p&gt;3.&amp;nbsp; Make a Workflow on the Case Comments object which fires when Case: Closed equals True (see second screenshot).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/29/validation2.png" onclick="window.open(this.href, '_blank', 'width=792,height=451,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"&gt;&lt;img height="56" border="0" width="100" alt="Validation2" title="Validation2" src="http://blogs.salesforce.com/support/images/2008/10/29/validation2.png" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt;
4.&amp;nbsp; Make a Field Update in that workflow which sets the No More Comments field to true.&lt;/p&gt;

&lt;p&gt;5.&amp;nbsp; Activate the workflow rule!&lt;/p&gt;

&lt;p&gt;Now, when you try to submit a comment on a closed case, the workflow will fire on the case comment.&amp;nbsp; This will make the modification to the No More Comments field on the Case to set it to true, which will violate the validation rule and disallow the save, showing the error &amp;quot;You cannot add comments to a closed case.&amp;quot; (see triumphant third screenshot)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/29/validation3.png" onclick="window.open(this.href, '_blank', 'width=800,height=456,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"&gt;&lt;img height="57" border="0" width="100" alt="Validation3" title="Validation3" src="http://blogs.salesforce.com/support/images/2008/10/29/validation3.png" style="margin: 0px 5px 5px 0px; float: left;" /&gt;&lt;/a&gt;
Workflow From Case Comments to the rescue!&lt;/p&gt;

&lt;p&gt;-Marco Casalaina&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/10/how-to-stop-peo.html</feedburner:origLink></entry>
  <entry>
    <title>Workflow From Case Comments!</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/423252111/workflow-from-c.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=57106411" title="Workflow From Case Comments!" />
    <id>tag:typepad.com,2003:post-57106411</id>
    <issued>2008-10-16T18:58:18-07:00</issued>
    <modified>2008-10-17T01:59:02Z</modified>
    <created>2008-10-17T01:58:18Z</created>
    <summary>I am pleased to report that the Winter '09 release includes a feature that customers have been asking about for years: Workflow From Case Comments! Workflow From Case Comments gives you the ability to create a workflow rule on the...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;I am pleased to report that the Winter '09 release includes a feature that customers have been asking about for years: Workflow From Case Comments!&lt;/p&gt;

&lt;p&gt;&lt;a onclick="window.open(this.href, '_blank', 'width=467,height=240,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/16/shot1_3.png"&gt;&lt;img height="102" border="0" width="200" src="http://blogs.salesforce.com/support/images/2008/10/16/shot1_3.png" title="Shot1_3" alt="Shot1_3" style="margin: 0px 0px 5px 5px; float: right;" /&gt;&lt;/a&gt; Workflow From Case Comments gives you the ability to create a workflow rule on the Case Comments object.&amp;nbsp; From that rule, you can create a field update that takes effect on either the comment itself or on the parent case.&lt;/p&gt;

&lt;p&gt;This means that you can finally create those workflows you've been waiting for!&lt;/p&gt;

&lt;p&gt;For example, let's say I have a process whereby I set my case to a status of &amp;quot;Awaiting Customer &lt;a href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/16/shot2.png" onclick="window.open(this.href, '_blank', 'width=737,height=613,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"&gt;&lt;img height="166" border="0" width="200" alt="Shot2" title="Shot2" src="http://blogs.salesforce.com/support/images/2008/10/16/shot2.png" style="margin: 0px 0px 5px 5px; float: right;" /&gt;&lt;/a&gt;
Response&amp;quot; when I'm waiting for the customer to get back to me.&amp;nbsp; Now my customer logs into the Customer Portal and adds a comment to the case.&amp;nbsp; That constitutes a response, so the system should automatically set my case back to a &amp;quot;Working&amp;quot; status. &lt;/p&gt;

&lt;p&gt;The screenshots shown here to the right document how I wrote a workflow that does just that.&amp;nbsp; All I have to do is write a workflow rule on Case Comment with the requisite criteria (and the criteria can refer to items from the Case as well).&amp;nbsp; Once that's done, I can make a field update that updates the status field on the case.
&lt;/p&gt;

&lt;p&gt;As people begin creating workflows from Case Comments, they inevitably notice that only Field Update and Outbound Message are available from these workflow rules.&amp;nbsp; Then they ask me, &lt;em&gt;what if I want to send an email?&lt;a onclick="window.open(this.href, '_blank', 'width=739,height=358,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="http://blogs.salesforce.com/.shared/image.html?/photos/uncategorized/2008/10/16/shot3_3.png"&gt;&lt;img height="96" border="0" width="200" src="http://blogs.salesforce.com/support/images/2008/10/16/shot3_3.png" title="Shot3_3" alt="Shot3_3" style="margin: 0px 0px 5px 5px; float: right;" /&gt;&lt;/a&gt;
&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As with workflow from Email Messages, Workflow From Case Comments is a &amp;quot;chaining&amp;quot; workflow – it can trigger other workflow. Right now you can't put an email alert on the comment for the same reason you can't put a task on it: because the Comments object does not support Activities as children. However, you can put an email alert on a workflow on the parent case, and that workflow will get triggered and send out the email (and the email will be associated to the parent case, as you might expect).&lt;/p&gt;

&lt;p&gt;So, although you can't send an email directly from a Workflow From Case Comments, you can put an email alert on the parent case.&amp;nbsp; So, for example, you might make a Workflow From Case Comments that updates a &amp;quot;Last Comment&amp;quot; field on the parent case with the text of the most recent comment, and then make a workflow on Case which emails out that last comment to certain members of the Case Team.&lt;/p&gt;

&lt;p&gt;Case Teams!&amp;nbsp; A little foreshadowing there – I'll cover that new Winter '09 feature in my next dispatch.&lt;/p&gt;

&lt;p&gt;Don't forget, post any questions about this blog entry on the &lt;a href="http://community.salesforce.com/sforce/board?board.id=general_development"&gt;General board on developer.force.com&lt;/a&gt; so that the whole community can benefit from it.&lt;/p&gt;

&lt;p&gt;-Marco Casalaina&lt;/p&gt;

&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/10/workflow-from-c.html</feedburner:origLink></entry>
  <entry>
    <title>Adding A Link Button To Your CTI Adapter</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/414060834/adding-a-link-b.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=56670875" title="Adding A Link Button To Your CTI Adapter" />
    <id>tag:typepad.com,2003:post-56670875</id>
    <issued>2008-10-07T11:52:58-07:00</issued>
    <modified>2008-10-07T18:55:03Z</modified>
    <created>2008-10-07T18:52:58Z</created>
    <summary>Here's another question that CTI customers often ask me, particularly in the new age of Visualforce: "Can we add a button to the adapter that navigates to a link and passes it some information about the call?" Yes you can!...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Here's another question that CTI customers often ask me, particularly in the new age of Visualforce: &amp;quot;Can we add a button to the adapter that navigates to a link and passes it some information about the call?&amp;quot;&lt;/p&gt;

&lt;p&gt;Yes you can!&amp;nbsp; You can do it with a minor modification to your CTI adapter code.&amp;nbsp; Here's how.&lt;/p&gt;

&lt;p&gt;In my example, I've made an Apex page called &amp;quot;QuickCreate&amp;quot; that takes in as parameters the ANI (or caller ID) and the DNIS (the number that was dialed).&amp;nbsp; Now I'm going to make a button in the CTI adapter that links to this page, passing it the appropriate information for the active call on the line.&lt;/p&gt;

&lt;p&gt;In your .h file, add something like this:&lt;/p&gt;

&lt;pre&gt;#define BUTTON_QUICK_CREATE 21&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;In your Initialize() method, add this:&lt;/p&gt;

&lt;pre&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;CCTIButton pQCButton;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;pQCButton.SetLabel(L&amp;quot;QuickCreate&amp;quot;);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;pQCButton.SetLongStyle(true);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;pQCButton.SetColor(COLOR_BEIGE);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;pQCButton.SetLinkURL(L&amp;quot;/001/e&amp;quot;);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;UIAddButtonToAllLines(BUTTON_QUICK_CREATE,&amp;amp;pQCButton);&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Just after you call OnCallRinging, add this code (I left in my OnCallRinging code for context –&amp;nbsp; add everything from the CCTILine down):&lt;/p&gt;

&lt;pre&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;int nReturn = CCTIUserInterface::OnCallRinging(sCallObjectId, nCallType, true, bLogCall, mapInfoFields, mapAttachedData, nLineNumber);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;CCTILine* pLine = GetLine(nReturn);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (pLine) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;CCTIButton* pQCButton = pLine-&amp;gt;GetButton(BUTTON_QUICK_CREATE);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (pQCButton) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;pQCButton-&amp;gt;SetLinkURL(L&amp;quot;/apex/QuickCreate?ANI=&amp;quot;+mapInfoFields[KEY_ANI]+L&amp;quot;&amp;amp;DNIS=&amp;quot;+mapInfoFields[KEY_DNIS]);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/pre&gt;

&lt;br /&gt;
&lt;p&gt;When the call is established, add the button to the line like this:&lt;/p&gt;

&lt;pre&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;listEnabledButtons.push_back(BUTTON_QUICK_CREATE);&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;And that's all there is to it!&amp;nbsp; Now you'll have a button that shows up whenever a line is active which, when clicked, will navigate to your Visualforce page.&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/10/adding-a-link-b.html</feedburner:origLink></entry>
  <entry>
    <title>Kiva and the Quick Mass Close Button</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/409689052/kiva-and-the-qu.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=56460075" title="Kiva and the Quick Mass Close Button" />
    <id>tag:typepad.com,2003:post-56460075</id>
    <issued>2008-10-02T15:22:55-07:00</issued>
    <modified>2008-11-21T00:25:42Z</modified>
    <created>2008-10-02T22:22:55Z</created>
    <summary>From time to time in my job as product manager of Service &amp; Support I come into contact with people who are using Salesforce.com to make a difference in the world. One such company is Kiva. Kiva is a microfinance...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;From time to time in my job as product manager of Service &amp;amp; Support I come into contact with people who are using Salesforce.com to make a difference in the world.&amp;nbsp; One such company is &lt;a href="http://www.kiva.org"&gt;Kiva&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;



&lt;p&gt;Kiva is a microfinance non-profit that allows you to lend
as little as $25 online to an entrepreneur in the developing world
that needs a loan. On &lt;a href="http://www.kiva.org/"&gt;Kiva&lt;/a&gt;, you act as a banker to the poor by
lending money to entrepreneurs in developing countries and then you get repaid.&amp;nbsp; Amazingly, in just 3 years, they've lent $44 million to 92,000 entrepreneurs, with an astonishing 98.5% repayment rate.&lt;/p&gt;

&lt;p&gt;Kiva is currently competing in the American Express Members Project, which will grant a grand prize of $1.5 million to the non-profit which garners the most votes from Amex cardmembers.&amp;nbsp; This money at Kiva could enable $30 million more loans to fund
60,000 more entrepreneurs so that they can lift themselves out of poverty.&lt;/p&gt;

&lt;p&gt;If you are an Amex cardmember, please &lt;a href="http://www.membersproject.com/project/view/P6KQEI"&gt;click here&lt;/a&gt; to vote for Kiva – it really is a good cause.&lt;/p&gt;

&lt;p&gt;And now on to the meat of today's post:&lt;/p&gt;

&lt;p&gt;Kiva runs all of its customer service operations on Salesforce.com.&amp;nbsp; A few weeks ago they came to me with a request which I've heard before: they wanted a Mass Case Close button that skips the Case Close screen and just closes the cases.&amp;nbsp; This is just a twist on the &lt;a href="http://blogs.salesforce.com/support/2008/07/the-quick-case.html"&gt;Quick Case Close button&lt;/a&gt; that I have written about previously on this blog, so I was happy to oblige.&lt;/p&gt;

&lt;p&gt;The code is quite simple:&lt;/p&gt;



&lt;pre&gt;{!REQUIRESCRIPT(&amp;quot;/soap/ajax/13.0/connection.js&amp;quot;)}&lt;br /&gt;&lt;br /&gt;var records = {!GETRECORDIDS($ObjectType.Case)};&lt;br /&gt;if (records[0] == null)&lt;br /&gt;{&lt;br /&gt;	alert(&amp;quot;Please select at least one case to close.&amp;quot;)&lt;br /&gt;} else {&lt;br /&gt;	//Get more info on the cases that were selected and generate a query out of it&lt;br /&gt;	var updateRecords = [];&lt;br /&gt;&lt;br /&gt;	//Iterate through the returned results&lt;br /&gt;	for (var recordIndex=0;recordIndex&amp;lt;records.length;recordIndex++) {&lt;br /&gt;		var caseUpdate = new sforce.SObject(&amp;quot;Case&amp;quot;);&lt;br /&gt;		caseUpdate.Id = records[recordIndex];&lt;br /&gt;		caseUpdate.Status = 'Closed';&lt;br /&gt;		updateRecords.push(caseUpdate);&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	var result = sforce.connection.update(updateRecords);&lt;br /&gt;	&lt;br /&gt;	//handle errors here&lt;br /&gt;	if (result.error) {&lt;br /&gt;	alert('There was an error processing one or more cases');&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	//Reload the list view to show what he now owns&lt;br /&gt;	parent.window.location.reload();&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;To add this code, go to Setup-&amp;gt;Cases-&amp;gt;Buttons and Links and make a new custom button called Mass Close.&amp;nbsp; Its Display Type should be set to List Button, its Behavior to Execute JavaScript, and its Content Source to OnClick JavaScript.&amp;nbsp; Paste the above code into the OnClick JavaScript field – but be sure to replace the &lt;em&gt;caseUpdate.Status = 'Closed';&lt;/em&gt; line with a status that is present in your org.&lt;/p&gt;

&lt;p&gt;Now you'll have to add this button to the Case list view.&amp;nbsp; To do&lt;br /&gt;this, go to Setup-&amp;gt;Cases-&amp;gt;Search Layouts.&amp;nbsp; Click Edit next to the&lt;br /&gt;Cases List View entry, and add your new button from the Available&lt;br /&gt;Buttons section to the Selected Buttons section.&lt;/p&gt;

&lt;p&gt;As with the Contention-Proof Accept Button, the trick here is that GETRECORDIDS call – it gets us the list of Case IDs that you selected from the list.&amp;nbsp; The rest here is simple, just put all those Case IDs into an array and set the case status fields to Closed, and call update.&amp;nbsp; Easy!&lt;/p&gt;

&lt;p&gt;Just imagine what other sorts of mass actions you could do with this method.&amp;nbsp; It's hard to fathom the creativity of the readers of this blog.&lt;/p&gt;

&lt;p&gt;And just in case you missed it: &lt;a href="http://www.membersproject.com/project/view/P6KQEI"&gt;Vote for Kiva!&lt;/a&gt; :)&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/10/kiva-and-the-qu.html</feedburner:origLink></entry>
  <entry>
    <title>The Contention-Proof Case Accept Button</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/371422124/the-contention.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=53460264" title="The Contention-Proof Case Accept Button" />
    <id>tag:typepad.com,2003:post-53460264</id>
    <issued>2008-08-21T18:06:48-07:00</issued>
    <modified>2008-08-22T01:06:55Z</modified>
    <created>2008-08-22T01:06:48Z</created>
    <summary>The case accept button is a handy thing. It shows up on queue views to allow members of that queue to mass-accept cases (actually, in the Agent Console it shows up in the Mass Action dropdown rather than as a...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;The case accept button is a handy thing.&amp;nbsp; It shows up on queue views to allow members of that queue to mass-accept cases (actually, in the Agent Console it shows up in the Mass Action dropdown rather than as a button, but it works the same).&lt;/p&gt;

&lt;p&gt;If you have a large queue, though, with lots of agents accepting cases at the same time, they may sometimes step on each others' toes.&amp;nbsp; If two agents accept the same cases at almost the same time, then the last one will win, and the first agent will not actually own the cases he thinks he just accepted.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.salesforce.com/support/anticontention-accept-but.html"&gt;Here's some custom button code I wrote&lt;/a&gt; which addresses this issue.&amp;nbsp; It only accepts cases that are still assigned to a queue; if the cases have been accepted by a user already, those cases will remain owned by the users who accepted them.&lt;/p&gt;

&lt;p&gt;To add this code, go to Setup-&amp;gt;Cases-&amp;gt;Buttons and Links and make a new
custom button called Accept Cases (or whatever label you'd like to use for this).&amp;nbsp; Its Display Type should be set to List Button, its Behavior to Execute JavaScript, and its Content
Source to OnClick JavaScript.&amp;nbsp; Paste &lt;a href="http://blogs.salesforce.com/support/anticontention-accept-but.html"&gt;the code from this link&lt;/a&gt; into the OnClick JavaScript field.&lt;/p&gt;

&lt;p&gt;Now you'll have to add this button to the Case list view.&amp;nbsp; To do this, go to Setup-&amp;gt;Cases-&amp;gt;Search Layouts.&amp;nbsp; Click Edit next to the Cases List View entry, and add your new button from the Available Buttons section to the Selected Buttons section.&lt;/p&gt;

&lt;p&gt;So how did I do this?&lt;/p&gt;

&lt;p&gt;Quite easily really.&amp;nbsp; Perhaps the most important part is the line that invokes &lt;em&gt;{!GETRECORDIDS($ObjectType.Case)}.&lt;/em&gt; This little-known merge field allows you to get a list of all the IDs that are selected in a list view or related list – really handy when you're trying to make buttons that act upon a large number of records.&lt;/p&gt;

&lt;p&gt;Once I have the IDs of the selected records, I run them through the also little-known &lt;em&gt;retrieve&lt;/em&gt; function to get more information about them.&amp;nbsp; The key to that retrieve call is getting Owner.Type – that will return a string for each case containing either &amp;quot;Queue&amp;quot; or &amp;quot;User&amp;quot; depending on what the type of each case's owner is.&amp;nbsp; A good lesson here is that GETRECORDIDS plus retrieve makes for a quick and powerful combination.&lt;/p&gt;

&lt;p&gt;Now I divide the cases into two piles: the &amp;quot;accept&amp;quot; pile for cases that are currently owned by a queue that we're going to allow this user to accept, and the &amp;quot;reject&amp;quot; pile of cases that have already been accepted by other users.&amp;nbsp; If there are any cases in the &amp;quot;accept&amp;quot; pile I call &lt;em&gt;update&lt;/em&gt; on it to update those cases, and then I give some feedback to the user of the changes that were made (and the changes that were rejected).&lt;/p&gt;

&lt;p&gt;And there we have it: the contention-proof case accept button.&amp;nbsp; Note that with just a couple of minor changes you can adapt this same code for use with leads and custom objects – any object that is ownable by a queue.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/08/the-contention.html</feedburner:origLink></entry>
  <entry>
    <title>An Even Better Way To Pop Visualforce Pages From CTI</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/365265206/an-even-bette-1.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=54206344" title="An Even Better Way To Pop Visualforce Pages From CTI" />
    <id>tag:typepad.com,2003:post-54206344</id>
    <issued>2008-08-14T18:08:19-07:00</issued>
    <modified>2008-08-15T01:08:25Z</modified>
    <created>2008-08-15T01:08:19Z</created>
    <summary>In a previous blog entry I posted a means of popping a Visualforce page from a CTI adapter. That method was somewhat complicated and required an adapter writer to modify some of the core CTI Toolkit library code. Digging into...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;In a previous blog entry I posted a means of popping a Visualforce
page from a CTI adapter.&amp;nbsp; That method was somewhat complicated and
required an adapter writer to modify some of the core CTI Toolkit
library code.&lt;/p&gt;

&lt;p&gt;Digging into it a little further, I recently came up with a much
simpler way to pop a Visualforce page from CTI.&amp;nbsp; There is one caveat
here:&amp;nbsp; using this method, your CTI adapter will &lt;em&gt;always&lt;/em&gt; pop this
Visualforce page – it won't try to do any other kind of search.&amp;nbsp; As
long as you're OK with having your Visualforce page do any searching
required, then this method is for you.&amp;nbsp; Here's how to do it.&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Make a Visualforce page that takes in ANI and a DNIS as
parameters on the URL.&amp;nbsp; You may also want to make it take in other
parameters that might be attached to the call.&lt;/li&gt;

&lt;li&gt;Whenever you call CCTIUserInterface::OnCallRinging to set the
adapter to its &amp;quot;call ringing&amp;quot; mode, set the third parameter to false. 
This disables the native adapter search mechanism.&lt;/li&gt;

&lt;li&gt;After every call to OnCallRinging add this code (replacing the &amp;quot;YourPageHere&amp;quot; with the actual name of your page):&lt;/li&gt;&lt;/ol&gt;

&lt;pre&gt;CCTIParty* pParty = pLine-&amp;gt;GetPartyByANI(mapInfoFields[KEY_ANI]);&lt;br /&gt;if (pParty) {&lt;br /&gt;	RelObjSetList relObjs;&lt;br /&gt;	CCTIRelatedObjectSet* pSet = &lt;br /&gt;		new CCTIRelatedObjectSet(L&amp;quot;Visualforce&amp;quot;,L&amp;quot;Caller Info&amp;quot;,L&amp;quot;Caller Info&amp;quot;);&lt;br /&gt;	pSet-&amp;gt;SetVisible(true);&lt;br /&gt;	relObjs.push_back(pSet);&lt;br /&gt;&lt;br /&gt;	std::wstring apexUrl = L&amp;quot;apex/YourPageHere?&amp;quot;;&lt;br /&gt;	apexUrl += L&amp;quot;ANI=&amp;quot; + mapInfoFields[KEY_ANI];&lt;br /&gt;	apexUrl += L&amp;quot;&amp;amp;DNIS=&amp;quot; + mapInfoFields[KEY_DNIS];&lt;br /&gt;&lt;br /&gt;	CCTIRelatedObject* pObject = new CCTIRelatedObject(apexUrl,L&amp;quot;Click To View&amp;quot;);&lt;br /&gt;	pObject-&amp;gt;SetVisible(true);&lt;br /&gt;	pSet-&amp;gt;AddRelatedObject(pObject);&lt;br /&gt;&lt;br /&gt;	pParty-&amp;gt;AddRelatedObjectSets(relObjs);&lt;br /&gt;}&lt;br /&gt;UIRefresh();&lt;/pre&gt;

&lt;p&gt;This code verbatim added to your adapter just after you call
OnCallRinging will cause it to pop to the Visualforce page.&amp;nbsp; The
Visualforce page can figure out what it should search on based on the
ANI and DNIS that's passed in via the URL.&lt;/p&gt;

&lt;p&gt;To take this a step further, you can also append all the members of
mapAttachedData to the URL, which will enable you to pass any attached
data (say, caller entered digits in the IVR) to your Visualforce page.&lt;/p&gt;

&lt;p&gt;One more thing, though: usually, when the CTI adapter pops an
object, it tries to add that object to the call log.&amp;nbsp; However, a
Visualforce page cannot be added to the call log, and if you try to add
one, it will cause the call log to fail upon saving.&amp;nbsp; So you'll want to
override the function that adds objects to the call log to ignore
Visualforce pages.&amp;nbsp; You can do so by overriding UIAddLogObject in your
subclass of CCTIUserInterface, like this (replacing the
CDemoUserInterface with the name of your subclass, of course):&lt;/p&gt;

&lt;pre&gt;void CDemoUserInterface::UIAddLogObject(PARAM_MAP&amp;amp; parameters) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;std::wstring sId = parameters[KEY_ID];&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (sId.find(L&amp;quot;apex&amp;quot;) == std::wstring::npos) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;CCTIUserInterface::UIAddLogObject(parameters);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Obviously you'll have to add a corresponding method header to your .h file also.&lt;/p&gt;

&lt;p&gt;To genericize this, you might consider adding a parameter to your
Call Center Definition File (that XML file you distribute to your
customers) that specifies the Visualforce page to pop to.&amp;nbsp; If the
customer specifies this page in the setup, then always pop to it;
otherwise take the normal route of searching for a Salesforce.com
object and popping what you find.&lt;/p&gt;

&lt;p&gt;And by the way:&lt;/p&gt;

&lt;p&gt;Let's say you want your Visualforce page to add an object to the
log.&amp;nbsp; As I mentioned earlier you can't put the Visualforce page itself
in the log, but you can send a message to the CTI adapter to have it
add an object to the log.&lt;/p&gt;

&lt;p&gt;All you have to do is have your Visualforce page call the following Javascript function:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;sendCTIMessage('ADD_LOG_OBJECT?ID='+entityId+'&amp;amp;amp;OBJECT_LABEL='
+
escape(entityLabel)+'&amp;amp;amp;ENTITY_NAME='+entityDevName+'&amp;amp;amp;OBJECT_NAME='
+ escape(entityName));&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;where:&lt;br /&gt;entityId = the Salesforce.com ID of the object you want to add to the log&lt;br /&gt;entityLabel = the name of the object you want to add to the log (like &amp;quot;Lead&amp;quot; or &amp;quot;My Custom Object&amp;quot;)&lt;br /&gt;entityDevName = the API name of the object you're adding (like &amp;quot;Lead&amp;quot; or &amp;quot;My_Custom_Object__c&amp;quot;)&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/08/an-even-bette-1.html</feedburner:origLink></entry>
  <entry>
    <title>Case Age In Business Hours</title>
    <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/typepad/Successforce/support/~3/358762967/case-age-in-bus.html" />
    <link rel="service.edit" type="application/x.atom+xml" href="http://www.typepad.com/t/atom/weblog/blog_id=483439/entry_id=53560238" title="Case Age In Business Hours" />
    <id>tag:typepad.com,2003:post-53560238</id>
    <issued>2008-08-07T13:52:10-07:00</issued>
    <modified>2008-08-07T21:07:10Z</modified>
    <created>2008-08-07T20:52:10Z</created>
    <summary>I am pleased to announce that we have released an AppExchange application called Case Age In Business Hours (click link for the AppExchange listing) under the Salesforce Labs banner. In this post I'll explain what it does, how it does...</summary>
    <author>
      <name>Marco Casalaina</name>
    </author>
    <dc:subject>Best Practices</dc:subject>

    <content type="html" xml:lang="en-US" xml:base="http://blogs.salesforce.com/support/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;I am pleased to announce that we have released an AppExchange application called &lt;a href="https://www.salesforce.com/appexchange/detail_overview.jsp?id=a0330000005lSqLAAU"&gt;Case Age In Business Hours&lt;/a&gt; (click link for the AppExchange listing) under the Salesforce Labs banner.&amp;nbsp; In this post I'll explain what it does, how it does it, and how you can modify the code if you so desire to make it do more.&lt;/p&gt;

&lt;p&gt;So first, what does it do?&amp;nbsp; More than its name suggests, actually.&amp;nbsp; First, and most obviously, it calculates the Case Age In Business Hours for your closed cases.&amp;nbsp; Fancy that.&amp;nbsp; It also has another useful function, though: it includes two more fields called Time With Support and Time With Customer that distinguish between time spent by your support team and time spent awaiting the customer.&amp;nbsp; Note that these new fields will only be accurate for closed cases -- I'll explain why in a bit.&lt;/p&gt;

&lt;p&gt;It sounds like it might be complex, doesn't it?&amp;nbsp; A few years ago, back in my full-time developer days, I wrote some code that calculated time differences in business hours, taking into account time zone differences, daylight savings, and all that jazz.&amp;nbsp; It was hundreds and hundreds of lines of code, and it took me days to get it right.&amp;nbsp; My pinkies still twitch at the thought of it.&lt;/p&gt;

&lt;p&gt;Thankfully, some of the capabilities we recently added to the Force.com platform make the Case Age In Business Hours package a cinch.&amp;nbsp; It does everything my old hunk of code did and more, but if you look at the trigger which forms the basis of this package, there are only 55 lines of code, and half the lines are comments or whitespace.&lt;/p&gt;

&lt;p&gt;What made it all possible are the BusinessHours methods in Apex, particularly BusinessHours.diff.&amp;nbsp; You pass BusinessHours.diff two times and a set of Business Hours (and you can define as many sets of Business Hours as you want at Setup-&amp;gt;Company Info-&amp;gt;Business Hours) -- and it spits back at you the time difference in business hours!&amp;nbsp; It does all the time zone translation and daylight savings nastiness for you, and all you have to do is call the method.&amp;nbsp; That's it!&lt;/p&gt;

&lt;p&gt;Now for the interesting part, though: how about those Time With Support and Time With Customer fields?&amp;nbsp; How do we figure that out?&lt;/p&gt;

&lt;p&gt;Well, if you install the package, you'll notice that it also installs a custom object and tab called &amp;quot;Stop Statuses.&amp;quot;&amp;nbsp; To set it up, you access this tab and add the names of the case statuses you'd use when you're waiting for your customer.&amp;nbsp; Some people have &amp;quot;Awaiting Customer Response&amp;quot; or &amp;quot;Awaiting Customer Validation&amp;quot; -- some just have &amp;quot;On Hold.&amp;quot;&amp;nbsp; Whatever your statuses may be, add them all in the Stop Statuses section.&amp;nbsp; Then, whatever time your case spends in one of those statuses will be tallied to the Time With Customer field -- and any time your case spends &lt;em&gt;not&lt;/em&gt; in a stop status (and not in a closed status, of course) will be added to to the Time With Support field.&lt;/p&gt;

&lt;p&gt;Now what if you want to take it to the next level -- let's say you want to add a bucket and measure Time With Tier 1, Time With Tier 2, and Time With Customer?&amp;nbsp; Well, that wouldn't be so hard -- you'd just have to factor in the owner as well as the status when deciding what times go in what buckets.&lt;/p&gt;

&lt;p&gt;Before we begin, remember that because the Business Hours functionality is new, this Apex will only compile against the 13.0 API and higher (13.0 being the latest as of the Summer '08 release).&amp;nbsp; If you haven't got the latest &lt;a href="http://wiki.apexdevnet.com/index.php/Force.com_IDE"&gt;Force.com IDE plugin&lt;/a&gt;, now would be a wonderful time to download it.&amp;nbsp; It makes Apex development much easier.&lt;/p&gt;

&lt;p&gt;First, we'll have to add some fields to Case to store this bucket. Let's call them Time With Tier 1 and Time With Tier 2 (with corresponding API names Time_With_Tier_1__c and Time_With_Tier_2__c respectively).&lt;/p&gt;

&lt;p&gt;Now we'll modify the trigger a little to accommodate these new buckets.&amp;nbsp; First, we'll need to figure out if the current user is a Tier 1 or a Tier 2 agent.&amp;nbsp; Let's assume (for the sake of simplicity) that we have two queues, Tier 1 and Tier 2, and that the current case owner will either be in one or the other.&amp;nbsp; It is admittedly a simplistic example, but this is a blog post, not a book.&lt;/p&gt;

&lt;p&gt;All you really need to do is add some code after this line:&lt;/p&gt;

&lt;pre&gt;Double timeSinceLastStatus = BusinessHours.diff(hoursToUse, updatedCase.Last_Status_Change__c, System.now())/3600000.0;&lt;/pre&gt;

&lt;p&gt;That's the code that actually figures out how many business hours have passed since the last status change.&amp;nbsp; At this point, you have the time you need to add to a bucket -- now all you have to do is find the right bucket to add it to.&lt;/p&gt;

&lt;p&gt;In the package, the bucketing code is pretty simple -- either the case spent the time since the last status change in a stop status, or it didn't:&lt;/p&gt;

&lt;pre&gt;if (stopStatusSet.contains(oldCase.Status)) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Customer__c += timeSinceLastStatus;&lt;br /&gt;} else {&lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Support__c += timeSinceLastStatus;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;We'll have to modify this statement to figure out whether the case owner is in tier 1, and then assign the time to the proper bucket.&amp;nbsp; First, let's find out if the owner in tier 1:&lt;/p&gt;

&lt;pre&gt;Boolean ownerIsTier1 = false;&lt;br /&gt;//Search the Tier 1 queue for this user&lt;br /&gt;GroupMember groupMember = [Select Id from GroupMember g where g.Group.Name='Tier 1' and &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;g.UserOrGroupId=:updatedCase.OwnerId];&lt;br /&gt;if (groupMember != null || updatedCase.Owner.Name == 'Tier 1') {&lt;br /&gt;&amp;nbsp; &amp;nbsp; //We found the user in the Tier 1 queue!&lt;br /&gt;&amp;nbsp; &amp;nbsp; ownerIsTier1 = true;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;The variable ownerIsTier1 will now be true if either the owner was found in the Tier 1 queue or if the owner is the Tier 1 queue itself.&amp;nbsp; Now that we've figured that out, we can put the time in the right bucket:&lt;/p&gt;

&lt;pre&gt;//We decide which bucket to add it to based on whether it was in a stop status before&lt;br /&gt;if (stopStatusSet.contains(oldCase.Status)) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; //This still goes in the customer bucket!&lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Customer__c += timeSinceLastStatus;&lt;br /&gt;} else {&lt;br /&gt;&amp;nbsp; &amp;nbsp; //This is time with support -- let's see which tier's bucket we put it in&lt;br /&gt;&amp;nbsp; &amp;nbsp; if (ownerIsTier1) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; updatedCase.Time_With_Tier_1__c += timeSinceLastStatus;&lt;br /&gt;&amp;nbsp; &amp;nbsp; } else {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; updatedCase.Time_With_Tier_2__c += timeSinceLastStatus;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Finally, we change the Case Age In Business Hours total code a little:&lt;/p&gt;

&lt;pre&gt;if (closedStatusSet.contains(updatedCase.Status)) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Case_Age_In_Business_Hours__c = &lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Customer__c + &lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Tier_1__c +&lt;br /&gt;&amp;nbsp; &amp;nbsp; updatedCase.Time_With_Tier_2__c;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;And there we have it.&amp;nbsp; Extending this example, you can calculate business hours times for all kinds of buckets.&amp;nbsp; Just imagine the reporting possibilities?&amp;nbsp; I can hear call center managers around the globe rubbing their hands together in glee.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.adnsandbox.com/media/samples/CalculateBusinessHoursAges.trigger.txt"&gt;Here's the finished trigger&lt;/a&gt; modified per the example given here.&amp;nbsp; I'll leave it to you to write the test cases for it.&lt;/p&gt;

&lt;p&gt;A little earlier I noted that these fields are only accurate for closed cases.&amp;nbsp; Why do you suppose that is?&lt;/p&gt;

&lt;p&gt;Back in high school, my creative writing teacher used to say that if you want to hold your reader's attention, you have to leave an unresolved mystery until the end.&amp;nbsp; Well, if you're still reading this, I guess it worked -- thanks Mrs. T!&amp;nbsp; &lt;/p&gt;

&lt;p&gt;The answer to today's unresolved mystery is that these fields don't measure the difference between the time the case was opened and &lt;em&gt;now&lt;/em&gt; -- they measure the difference between the time the case was opened and &lt;em&gt;the last time the case status changed&lt;/em&gt;.&amp;nbsp; That's because only a change to the case can trigger the Apex which updates these fields, and I deemed a status change the most appropriate change to perform this sort of recalculation.&amp;nbsp; Once the case is closed, these fields are frozen -- even if you change it from one closed state to another, they won't budge (if you reopen the case, on the other hand, they'll start tallying again).&amp;nbsp; The fact of the matter is, then, that only once the case is closed will you have a final tally of Time With Customer, Time With Support, and Case Age In Business Hours.&lt;/p&gt;
&lt;/div&gt;
</content>



  <feedburner:origLink>http://blogs.salesforce.com/support/2008/08/case-age-in-bus.html</feedburner:origLink></entry>

</feed>
