<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Anthony Victorio</title>
	<atom:link href="http://www.anthonyvictorio.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.anthonyvictorio.com</link>
	<description>SEO, SEM, Webmaster, Web Design, Salesforce Developer, Freelancer</description>
	<lastBuildDate>Sun, 12 Jun 2011 21:32:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Salesforce Roll-Up Summary Trigger Revised</title>
		<link>http://www.anthonyvictorio.com/salesforce/roll-up-summary-trigger/</link>
		<comments>http://www.anthonyvictorio.com/salesforce/roll-up-summary-trigger/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 17:17:16 +0000</pubDate>
		<dc:creator>Anthony Victorio</dc:creator>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[apex]]></category>
		<category><![CDATA[roll-up summary]]></category>
		<category><![CDATA[trigger]]></category>

		<guid isPermaLink="false">http://www.anthonyvictorio.com/?p=100</guid>
		<description><![CDATA[Why on earth would anybody want a Salesforce trigger to perform a roll-up summary type function when Salesforce already provides you with Roll-Up Summary fields? The answer may not be apparent until you begin to be inhibited by the limitations of Roll-Up Summary fields. So what are these limitations? Objects have a limit of 10 maximum roll-up summary fields Objects on the master side of a master-detail relationship can have roll-up summary fields Lookup relationships do not support roll-up summary fields Long text area, multi-select picklist, and system fields are not supported as filters or bases for roll-up summary fields Campaign [...]]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_108" class="wp-caption alignright" style="width: 310px"><img src="http://www.anthonyvictorio.com/media/salesforce-roll-up-summary-trigger.png" alt="Salesforce Roll-Up Summary Trigger" title="Salesforce Roll-Up Summary Trigger" width="300" height="250" class="size-full wp-image-108" /><p class="wp-caption-text">Salesforce Roll-Up Summary Trigger</p></div>
<p>Why on earth would anybody want a <strong>Salesforce trigger to perform a roll-up summary</strong> type function when Salesforce already provides you with Roll-Up Summary fields?</p>
<p>The answer may not be apparent until you begin to be inhibited by the limitations of Roll-Up Summary fields. So what are these limitations?</p>
<ul>
<li>Objects have a limit of 10 maximum roll-up summary fields</li>
<li>Objects on the master side of a master-detail relationship can have roll-up summary fields</li>
<li>Lookup relationships do not support roll-up summary fields</li>
<li>Long text area, multi-select picklist, and system fields are not supported as filters or bases for roll-up summary fields</li>
<li>Campaign roll-up summary fields do not recalculate values when Lead or Contacts are deleted</li>
</ul>
<p>Colin Loretz and Jeff Douglas have both developed very similar solutions for combating these challenges through the use of Salesforce apex triggers:</p>
<ul>
<li><a href="http://blog.jeffdouglas.com/2009/07/30/roll-up-summary-fields-with-lookup-relationships-part-1/">Roll-Up Summary Fields with Lookup Relationships Part 1</a> &#8211; Jeff Douglas</li>
<li><a href="http://colinloretz.com/2008/10/salesforce-rollup-summary-fields-using-apex-code/">Salesforce Rollup Summary Fields using Apex Code</a> &#8211; Colin Loretz</li>
</ul>
<p>However, both approaches still face some challenges:</p>
<ul>
<li><strong>Governor Limits</strong> &#8211; If their list&lt;&gt; contains more than the allowed amount (currently 10,000) then an exception will be thrown</li>
<li><strong>Invalid Query Locator</strong> &#8211; Colin&#8217;s solutions relies on sub-query (related record) calls, which tend to break when processing thousands of records.</li>
</ul>
<p>To address these challenges I put together an apex trigger that reduces the size of my list by taking advantage of sets, the SOQL SUM and Group By functions and the AggregateResult sObject.  I also used maps to retrieve my sum totals which eliminates the invalid query locator errors.</p>
<p>The following trigger sums a number field on a custom object and then updates an Opportunity number field with the total. The structure is as follows:</p>
<ul>
<li>Opportunity
<ul>
<li>Payments (Lookup Relationship on Opportunity__c)</li>
</ul>
</li>
</ul>
<p><strong>Salesforce Roll-Up Summary Trigger</strong></p>
<pre class="brush: apex; title: ; notranslate">
trigger OpportunityRollUpPayments on Payment__c (after delete, after insert, after update) {

  //Limit the size of list by using Sets which do not contain duplicate elements
  set&lt;Id&gt; OpportunityIds = new set&lt;Id&gt;();

  //When adding new payments or updating existing payments
  if(trigger.isInsert || trigger.isUpdate){
    for(Payment__c p : trigger.new){
      OpportunityIds.add(p.Opportunity__c);
    }
  }

  //When deleting payments
  if(trigger.isDelete){
    for(Payment__c p : trigger.old){
      OpportunityIds.add(p.Opportunity__c);
    }
  }

  //Map will contain one Opportunity Id to one sum value
  map&lt;Id,Double&gt; OpportunityMap = new map &lt;Id,Double&gt;();

  //Produce a sum of Payments__c and add them to the map
  //use group by to have a single Opportunity Id with a single sum value
  for(AggregateResult q : [select Opportunity__c,sum(Amount__c)
    from Payment__c where Opportunity__c IN :OpportunityIds group by Opportunity__c]){
      OpportunityMap.put((Id)q.get('Opportunity__c'),(Double)q.get('expr0'));
  }

  List&lt;Opportunity&gt; OpportunitiesToUpdate = new List&lt;Opportunity&gt;();

  //Run the for loop on Opportunity using the non-duplicate set of Opportunities Ids
  //Get the sum value from the map and create a list of Opportunities to update
  for(Opportunity o : [Select Id, Total_Payments__c from Opportunity where Id IN :OpportunityIds]){
    Double PaymentSum = OpportunityMap.get(o.Id);
    o.Total_Payments__c = PaymentSum;
    OpportunitiesToUpdate.add(o);
  }

  update OpportunitiesToUpdate;
}
</pre>
<p>I have tested this method and have successfully updated over 10,000 Opportunity records with over 35,000 payment records through the bulk-api, so I feel good about it.  When I get around to it I&#8217;ll write up the test class and publish it here.</p>
<p>Update: Here&#8217;s the test class.</p>
<pre class="brush: apex; title: ; notranslate">
@isTest
private class TestOpportunityRollUpPayments {

    static testMethod void myUnitTest() {

        Profile pf = [Select Id from Profile where Name = 'System Administrator'];

        User u = new User();
        u.FirstName = 'Test';
        u.LastName = 'User';
        u.Email = 'testuser@test123456789.com';
        u.CompanyName = 'test.com';
        u.Title = 'Test User';
        u.Username = 'testuser@test123456789.com';
        u.Alias = 'testuser';
        u.CommunityNickname = 'Test User';
        u.TimeZoneSidKey = 'America/Mexico_City';
        u.LocaleSidKey = 'en_US';
        u.EmailEncodingKey = 'ISO-8859-1';
        u.ProfileId = pf.Id;
        u.LanguageLocaleKey = 'en_US';
        insert u;

        system.runAs(u){

            Opportunity o = new Opportunity();
            o.Name = 'Test Opportunity';
            o.StageName = 'Closed Won';
            o.CloseDate = system.today();
            insert o;

            system.assertEquals(o.Total_Payments__c, null);

            //Test payments on insert
            Payment__c p1 = new Payment__c();
            p1.Opportunity__c = o.Id;
            p1.Amount__c = 100;
            insert p1;

            Opportunity ou1 = [select Total_Payments__c from Opportunity where Id = :o.Id];
            system.assertEquals(ou1.Total_Payments__c,p1.Amount__c);

            //Test payments on update
            Payment__c p1u = [select Amount__c from Payment__c where Id = :p1.Id];
            p1u.Amount__c = 200;
            update p1u;

            Opportunity ou2 = [select Total_Payments__c from Opportunity where Id = :o.Id];
            system.assertEquals(ou2.Total_Payments__c,p1u.Amount__c);

            //Test payments on second insert
            Payment__c p2 = new Payment__c();
            p2.Opportunity__c = o.Id;
            p2.Amount__c = 800;
            insert p2;

            AggregateResult ag1 = [select sum(Amount__c) from Payment__c where Opportunity__c = :o.Id];

            Opportunity ou3 = [select Total_Payments__c from Opportunity where Id = :o.Id];
            system.assertEquals(ou3.Total_Payments__c,ag1.get('expr0'));

            //Test payment on delete
            delete p2;

            AggregateResult ag2 = [select sum(Amount__c) from Payment__c where Opportunity__c = :o.Id];

            Opportunity ou4 = [select Total_Payments__c from Opportunity where Id = :o.Id];
            system.assertEquals(ou4.Total_Payments__c,ag2.get('expr0'));

        }

    }

}
</pre>
<p>To see this trigger in action jump over to the <a href="http://avictorio-developer-edition.na9.force.com/roll_up_summary_trigger?Id=006E00000026787IAA">roll-up summary trigger demo</a>.</p>
<p>Do you see any holes in my code? Please point them out in the comment section below :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.anthonyvictorio.com/salesforce/roll-up-summary-trigger/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Salesforce Apex &amp; VisualForce Syntax Highlighter for WordPress</title>
		<link>http://www.anthonyvictorio.com/salesforce/syntax-highlighter/</link>
		<comments>http://www.anthonyvictorio.com/salesforce/syntax-highlighter/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 05:00:30 +0000</pubDate>
		<dc:creator>Anthony Victorio</dc:creator>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[apex]]></category>
		<category><![CDATA[highlighter]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[visualforce]]></category>

		<guid isPermaLink="false">http://www.anthonyvictorio.com/?p=79</guid>
		<description><![CDATA[If you&#8217;ve ever used a search engine to find help on Salesforce development, then you&#8217;re probably familiar with Jeff Douglas. He is the inspiration behind this section of my blog. As a developer, I often find my self accumulating an ever growing array of help documents, useful functions, tips, shortcuts and commonly repeated code. Rather than hog them for my self, I decided to do what Jeff has been doing and share my knowledge with the online community. Before I started to blog about Salesforce, I began looking for syntax highlighter wordpress plugins that might meet my needs. While the [...]]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_97" class="wp-caption alignright" style="width: 312px"><img src="http://www.anthonyvictorio.com/media/salesforce-apex-visualforce-highlighter.png" alt="Salesforce Apex / Visualforce Syntax Highlighter" title="Salesforce Apex / Visualforce Syntax Highlighter" width="302" height="252" class="size-full wp-image-97" /><p class="wp-caption-text">Salesforce Apex / Visualforce Syntax Highlighter</p></div>If you&#8217;ve ever used a search engine to find help on Salesforce development, then you&#8217;re probably familiar with <a href="http://blog.jeffdouglas.com/">Jeff Douglas</a>.  He is the inspiration behind this section of my blog. As a developer, I often find my self accumulating an ever growing array of help documents, useful functions, tips, shortcuts and commonly repeated code. Rather than hog them for my self, I decided to do what Jeff has been doing and share my knowledge with the online community.</p>
<p>Before I started to blog about Salesforce, I began looking for syntax highlighter wordpress plugins that might meet my needs.  While the options were plentiful, none were specific to Salesforce and so I took it upon my self to develop my own. Now, to begin my first Salesforce post I share this plugin with you and a bit of information about how it came together.</p>
<p>Thanks to a post by Eric Santiago on his version of a <a href="http://www.ericsantiago.com/eric_santiago/2011/03/visualforce-apex-syntax-highlighter-for-typepad.html">Visualforce Syntax Highlighter</a> for Typepad and a post by Alex on <a href="http://www.viper007bond.com/wordpress-plugins/syntaxhighlighter/adding-a-new-brush-language/">adding new brushes to Syntax Highlighter Evolved</a> I was able to put together a WordPress plugin that works alongside the SyntaxHighlighter Evolved plugin in order to provide Apex &#038; VisualForce sytanx highlighting.</p>
<p>You can download the plugin by clicking on this link: <a href="http://www.anthonyvictorio.com/media/visualforce-sh.zip">SyntaxHighlighter Evolved: Salesforce Apex &#038; VisualForce Brush</a>.</p>
<p>I&#8217;ve submitted the plugin to the wordpress.org depository so hopefully it will appear there soon.</p>
<p>Once you&#8217;ve installed both plugins, you can begin writing your code by using the following shortcodes:</p>
<p>&#91;visualforce&#93; &#91;/visualforce&#93;<br />
&#91;apex&#93; &#91;/apex&#93;</p>
<p>Here&#8217;s an example of the Visualforce syntax:</p>
<pre class="brush: VisualForce; title: ; notranslate">
&lt;apex:page standardController=&quot;Opportunity&quot; &gt;
  &lt;apex:sectionHeader title=&quot;Cancellation Approval&quot;/&gt;
  &lt;apex:form &gt;
      &lt;apex:pageBlock title=&quot;Edit&quot; mode=&quot;edit&quot; id=&quot;thepageblock&quot;&gt;
          &lt;apex:pageblockButtons &gt;
              &lt;apex:commandButton value=&quot;Save&quot; action=&quot;{!save}&quot;/&gt;
          &lt;/apex:pageblockButtons&gt;

          &lt;apex:pageBlockSection columns=&quot;1&quot; title=&quot;Opportunity Details&quot;&gt;
          &lt;apex:outputField value=&quot;{!Opportunity.Name}&quot;/&gt;
          &lt;apex:outputField value=&quot;{!Opportunity.Customer_Name__c}&quot;/&gt;
          &lt;apex:outputField value=&quot;{!Opportunity.Hotel_Name__c}&quot;/&gt;

          &lt;apex:outputField value=&quot;{!Opportunity.Booked_Room_Nights__c}&quot;/&gt;
          &lt;apex:outputField value=&quot;{!Opportunity.Booked_Gross_Booking__c}&quot;/&gt;
          &lt;apex:outputField value=&quot;{!Opportunity.Request_To_Cancel__c}&quot;/&gt;
          &lt;/apex:pageBlockSection&gt;

          &lt;apex:pageBlockSection columns=&quot;1&quot; title=&quot;Approval Details&quot;&gt;
          &lt;apex:inputField value=&quot;{!Opportunity.Sales_Agent_Action__c}&quot; required=&quot;true&quot; /&gt;
          &lt;apex:inputField value=&quot;{!Opportunity.Cancellation_Is__c}&quot; required=&quot;true&quot; &gt;
              &lt;apex:actionSupport event=&quot;onchange&quot; rerender=&quot;thepageblock&quot; status=&quot;status&quot;/&gt;
          &lt;/apex:inputField&gt;
          &lt;apex:inputField value=&quot;{!Opportunity.Sales_Agent_Outcome__c}&quot; rendered=&quot;{!opportunity.Sales_Agent_Action__c == 'Called Customer' || opportunity.Sales_Agent_Action__c == 'Emailed Customer' || Opportunity.Cancellation_Is__c == 'Declined'}&quot; required=&quot;true&quot; style=&quot;width:500px;height:100px;&quot;/&gt;
          &lt;/apex:pageBlockSection&gt;
      &lt;/apex:pageBlock&gt;
  &lt;/apex:form&gt;
&lt;/apex:page&gt;
</pre>
<p>Here&#8217;s an example for the Apex syntax:</p>
<pre class="brush: apex; title: ; notranslate">
trigger CreateActivityFromPublicTask on Public_Task__c (after insert) {

  List&lt;Task&gt; TasksToCreate = new List&lt;Task&gt;();

  for (Public_Task__c pt : Trigger.new) {

    Task t = new Task();
    t.Priority = pt.Priority__c;
    t.ActivityDate = pt.Call_Back_Date__c;
    t.Call_Back_Time__c = pt.Call_Back_Time__c;
    t.Call_Back_Number__c = pt.Call_Back_Number__c;
    t.Description = pt.Comments__c;
    t.WhoId = pt.Lead__c;
    t.Status = pt.Status__c;
    t.Type = pt.Type__c;
    t.Subject = pt.Subject__c;
    t.IsReminderSet = pt.IsReminderSet__c;
    t.ReminderDateTime = pt.ReminderDateTime__c;
    t.OwnerId = pt.OwnerId;
    TasksToCreate.add(t);
  }
  if(TasksToCreate.size() &gt; 0) {
    insert TasksToCreate;
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.anthonyvictorio.com/salesforce/syntax-highlighter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>100 Days, 100 Successes &#8211; Obama’s First 100 Days in Office</title>
		<link>http://www.anthonyvictorio.com/blog/100-days-100-successes-obama%e2%80%99s-first-100-days-in-office/</link>
		<comments>http://www.anthonyvictorio.com/blog/100-days-100-successes-obama%e2%80%99s-first-100-days-in-office/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 15:03:35 +0000</pubDate>
		<dc:creator>Anthony Victorio</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.anthonyvictorio.com/blog/100-days-100-successes-obama%e2%80%99s-first-100-days-in-office/</guid>
		<description><![CDATA[100 Days, 100 Successes &#8211; Obama’s First 100 Days in Office Posted using ShareThis]]></description>
			<content:encoded><![CDATA[<p><a href=http://www.askdeb.com/blog/money/100-days-100-successes-obamas-first-100-days-in-office/>100 Days, 100 Successes &#8211; Obama’s First 100 Days in Office</a></p>
<p>Posted using <a href="http://sharethis.com">ShareThis</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.anthonyvictorio.com/blog/100-days-100-successes-obama%e2%80%99s-first-100-days-in-office/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Who is Anthony Victorio?</title>
		<link>http://www.anthonyvictorio.com/blog/anthony-victorio/</link>
		<comments>http://www.anthonyvictorio.com/blog/anthony-victorio/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 02:30:20 +0000</pubDate>
		<dc:creator>Anthony Victorio</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.anthonyvictorio.com/?p=3</guid>
		<description><![CDATA[Hello. I am Anthony Victorio. I would love to share all kinds of personal details about my self, however, identity theft has made me way too paranoid.  I can tell you that I was born in Peru and migrated to the US when I was very young.  I currently reside in Texas and make my living as a webmaster / web designer / seo consultant. I created this site to share personal aspects of my life with my friends and to showcase my professional work with colleagues. To see some of my work check out the &#8220;Portfolio&#8221; section listed on [...]]]></description>
			<content:encoded><![CDATA[<p>Hello. I am Anthony Victorio.</p>
<p>I would love to share all kinds of personal details about my self, however, identity theft has made me way too paranoid.  I can tell you that I was born in Peru and migrated to the US when I was very young.  I currently reside in Texas and make my living as a webmaster / web designer / seo consultant.</p>
<p>I created this site to share personal aspects of my life with my friends and to showcase my professional work with colleagues. To see some of my work check out the &#8220;Portfolio&#8221; section listed on the top menu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.anthonyvictorio.com/blog/anthony-victorio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

