Mar 14, 2016

Lab Coat Challenge 8: Scripting Scripts


Salesforce Devs, we have a Lab Coat Challenge for you challenge your ability to utilize queries and DMLs. Review the challenge, take a look at the starter code, and then give it your best attempt. If you come up with the right answer, you will earn a Lab Coat Badge.


Overview


Today’s challenge is related with queries and DMLs.

Challenge


There are two orgs. Org A has 10 Accounts that need to find their way into Org B. Org B has no accounts.  Neither org allows you to use Data Loading tools (Data Loader, Workbench, etc).  Both orgs allow you to run Apex. Write an Apex script that outputs an Apex script that will run on Org B and create those 10 Account records.

Starter Code  





Lab Coat Challenge 7: Merge Text




Salesforce Devs, we have a Lab Coat Challenge for you that will test your mental ability. Review the challenge, take a look at the starter code, and then give it your best attempt. If you come up with the right answer, you will earn a Lab Coat Badge. We'll share your success on Twitter!


Overview 


Today’s challenge has to do with merging text.

Challenge


Hi {!FirstName},

We hope you enjoy {!Number__c}.  Show us your {!ChallengeSkillset__c} chops!

Hang on..., that’s not a typo or a merge fail. It’s the gist of this Lab Coat Challenge. You’re developing a way to construct a dynamic query that includes all of the placeholders in a given piece of text. Your objective is to take in a string of text, with one or more merge fields, pluck out the fields, and build your query string out.

For example, for the above sample, your query string would need to pull in the FirstName field (IE:  SELECT Id, FirstName, ChallengeNumber__c, ChallengeSkillset__c…).


Starter Code


You must use the following code and can only add to the code provided below.






Lab Coat Challenge 6: Quick Mode



Hey there dev's and dev's-to-be! We have a 'Quick' Lab Coat Challenge for you. Review the challenge, take a look at the starter code, and then give it your best shot. Get the right answer and earn your Lab Coat Badge.


Overview


Today’s challenge has to do with finding the mode of a given set of integers


Challenge

Using the smallest amount of code (least statements - no run on lines of multiple statements!), determine what the “mode” (most frequent number) of a set of integers is. For more information on mode go to: http://www.mathgoodies.com/lessons/vol8/mode.html.  For this challenge, if the solution is multimodal (having more than one mode), choose the lowest number of the results (IE:  If 2, 3, and 10 are modes for a set of integers, the solution will be 2).


Starter Code

You must use the following code and can only add to the code provided below.


/*  LAB COAT CHALLENGE: What is the minimum amount of lines
   needed in order to find the mode of the following list
   of integers? */

//  lists of integers to be used in the asserts
list<Integer> numbers1 = new list<Integer> {2,5,1,2,7,1,2,6,4,6,2,3,8,9};
list<Integer> numbers2 = new list<Integer> {2,5,1,6,7,8,1,5};
list<Integer> numbers3 = new list<Integer> {5,4,7,1,7,2,3,5,4};
list<Integer> numbers4 = new list<Integer> {5,4,7,2,1,7,1,2,5,4};

//  Test your code
system.assertEquals(mode(numbers1), new set<Integer> {2});
system.assertEquals(mode(numbers2), new set<Integer> {1,5});
system.assertEquals(mode(numbers3), new set<Integer> {4,5,7});
system.assertEquals(mode(numbers4), new set<Integer>());

//  YOUR CHANGES START BELOW

//   Implement the following method
set<Integer> mode(list<Integer> listOfIntegersToTest) {
   set<Integer> returnValues = new set<Integer>();

   // Your code here

   return returnValues;

}

Nov 30, 2015

Salesforce Triggers, Workflow, and Process Builder






The Question:


How is it possible for triggers to fire three times on a single save of a record? There are many reasons this can happen in the Salesforce1 platform. Our problem had to do with Workflow and Process Builder. We were expecting only 1 extra trigger to fire because we were using workflow field updates and process builder field updates, figuring that the additional DML would be grouped at the end and fire one more time. But instead we found 2 extra triggers fired.


The Problem:


A DML (Data Manipulation Language) operation is happening and it causes the trigger to fire. Then, the workflow rule executes and that causes the trigger to fire a 2nd time. Then, the Process Builder flow fires and inside the Process Builder flow, the trigger fires a 3rd time.


When the Process Builder flow is deactivated, the trigger fires twice.  When the Process Builder flow is left active and all the workflow rules are deactivated, the trigger fires twice, as well.




The Solution:


The answer is to set a static variable during the first execution, and then reference this variable to determine whether or not subsequent code should be executed. But be careful in the unit tests; after each DML in unit test, the flag will have to be set to false again if you intend to try insert, then update, then update etc., since each unit test is in the same context and considered the "same execution."


Here is how the trigger starts out:








Further Exploration:


Many might have known the ‘before and after executions’ in the order of executions, but perhaps hadn’t seen that the Process Builder causes a third run.  The question arises, as to where the Process Builder runs in the order? A review of the Salesforce Developers Force.com Apex Developer’s Guide: Triggers and Workflow, does not list it in the order of execution running as it did in the example above.



The Process Builder can be set up to cause a re-execution. So one might still wonder if the Process Builder re-triggers from the top of the execution, entirely? The thinking of our team at CRM Science is that it is both Workflow, and Process Builder. One might have imagined that Salesforce would combine Workflow, and Process Builder, into the same steps so they don’t run trigger so much. On "busier" objects or objects prone to bulk inserts/updates through data loads, you may find yourself avoiding introducing processes into the mix. If you have the capability to do so, stick with triggers; at least, for now.


Considerations For Large Salesforce Orgs

In really large Salesforce Orgs triggers on core CRM objects can become a bane of an admin or developer’s existence if the last group in charge of the org didn’t control usage.  Stick to as few triggers as possible per object (ideal is one), as little logic as possible within the trigger bodies, and utilize a common trigger handler method for further processing. For developer friendly orgs, consider the creation of a control system, like a Custom setting, to easily enable and disable home-brewed triggers in your Production environment.
Have A Salesforce Puzzle? Let's Solve It Together! 
Contact Us Here.




Sep 15, 2015

Stop Drop & Rollback -- How to handle errors properly in Apex/Salesforce with Try, Catch, Rollback Best Practices

Visit our website




Smokey Says - Care will prevent 9 out of 10 Apex errors!
There are some assumptions that we know about when coding in Salesforce in regards to protecting the developer from saving partial-processed data in Salesforce.

- Any exceptions that happen in code(within the same entire execution) will roll back the entire execution so that all database changes leading up to the failure will not be committed to the database.  This is true for triggered code, page controllers, asynchronous code, etc.  This was a GREAT thing as I started developing in Salesforce and really protected the data for the customers.

- The above is only true if: 1. You are not using try/catch blocks around DML operations(which results in undesirable errors on top of standard pages or white-screen error pages from custom pages) 2. Or you are using try/catch blocks and are properly handling the error inside the 'catch'.

There are many uses of try/catch which I won't cover here but you can check that out here.

My Experience

The more custom work I did the more I realized that I was using try/catch all over the place but didn't immediately understand the dangerous implications of using it.  I've talked about this topic many times with other developers, explaining my experience, and it can be a complex one to discuss but I'll try to lay out some hypothetical situations.

Situations

  1. You want to use try/catch in a page controller so that you can show a friendly error on the screen for the user.  There are 2 DML operations in the 'button click' action, and say the error happens on the second DML.  So you tell the user there is an issue by adding a pagemessage.  Did you do anything to undo the 1st DML which was a success? Salesforce will not roll-back that DML for you because you've essentially "caught" the error that would have done that.  Result: Bad data. You need to roll-back.
  2. You've got a trigger on Case that will roll-up some custom information to the Account.  This important logic will keep the data in-check.  But sometimes there is an issue when you run the DML Update to the accounts, so you wrap the DML in a try/catch and perform a system.debug to figure things out a bit better.  You've deployed things like this to production since it is very rare.  By "catching" this error and the only handling you've done is a debug, you have told Salesforce not to roll-back the changes to the original Cases that fired the trigger.  You'll end up with Cases(newer changes) out of sync with Account(failed update) in your database.  The solution is that you need to attach a ".adderror()" to the appropriate Case records in the trigger which will tell salesforce to roll-back changes and will show your custom more descriptive error to the user(or to the calling code / external system). Result: Bad data. You need to .addError

Code Examples - VF Controller


VF Controller Good Example no try/catch - Standard exception handling, SF handles database protection KEY: Do nothing extra (Good)

VF Controller Bad Example with try/catch - Account will insert without the case
Since we are using try/catch below, we are able to show the user a nicer error message with the ApexPages.addMessage method. BUT, we are now taking over the standard salesforce pattern of "error and rollback". And we are forgetting to rollback ourselves.


VF Controller Good Example with try/catch - If Case fails, Account insert will rollback KEY: Using Database Rollback (Best Practice)


Code Examples - Trigger

Trigger Good Example no try/catch - Standard exception handling, SF handles database protection KEY: Do nothing extra (Good)


Trigger Bad example with try/catch - Account update could fail but we didn't stop the Cases from being inserted


Trigger Good example with try/catch - If Account update fails, we flag the Cases with an error which will show to user and prevent the Case inserts KEY: Use .addError() method (Best Practice)

Other Tips

- When using the generic exception class, it will catch any type of error besides for limits and some other situations. Be careful not to put too much inside the same Try block as it'll be more difficult to figure out what caused the error. Best practice would be use specific exception classes like dmlexception and only put a single DML in that try block.

- Make sure to test your catch blocks.  In your manual tests you can configure a dummy "requirement" on an object or a validation rule you know will fail, or leave out a required field. Then attempt the custom button, standard button, whatever it is that starts the code which should fail and see how your catch block operates.  For unit tests this could be more difficult but you could employ some special logic to conditionally fill in data or fail to fill in data in your code.  Say your controller would be looking for "Unit Test *** Fail DML Required Field" it could know to purposely clear a field on a record before the DML which would then fire your catch block.  Or you have a Unique field setup in an object and let your unit test try to insert 2 records with the same values in that field.  There's many other things you could do, up to you.

Dreamforce '15 Session: Enhanced Web Service Testing: A Better Mock Structure

Session Title: Enhanced Web Service Testing: A Better Mock Structure

When: Tuesday, 9/15/15 at 5:30 PM
Where: Moscone West - 2007

Details
Salesforce provides an interface for testing callouts named HttpCalloutMock used to cover remote callouts. While adequate for simple callouts, in the real world you often need something more flexible, as in the case of multiple and varying responses from the same or varying endpoints. More precise testing and coverage can be obtained by extending the standard interface. Join us as we demonstrate a solution to use to enable the flexibility required for complex integration and synchronization apps.

Deck:  http://bit.ly/df15_kirk_deck
Unmanaged Package:  http://bit.ly/df15_kirk_pack_v1_1
Original Blog Post:  http://blog.crmscience.com/2014/12/test-coverage-pattern-for-multi-callout.html

Sep 8, 2015

Lab Coat Challenges: Challenge #5 Now Available


Challenge 5: Magic 8 Ball

Hey developers (and budding developers)!

Dreamforce is next week!  Who saw that coming?  If you follow us on Twitter (@crmscience), you probably did. #CalendarCube.

Being next week, you might be strategizing when you're going to get your selfie in with SaaSy.  With this week's challenge, we wanted to give you a way to wake up in the morning and definitely have an answer for "Will I see SaaSy today?"
 
Objective
You'll be creating a magic 8 ball like method that returns a string.  This magic 8 ball, though, only answers one question... "Will I see SaaSy today?"  You know, because a Dreamforce without a SaaSy selfie is like eating a cupcake without icing.

Within the method, determine how to randomly select return one of the valid answers.

Click here for the full details, rules, and starter code!























Sep 7, 2015

Lab Coat Coat Challenges: Challenge #3 Responses!



Great round of submissions for this Lab Coat Challenge!

It's interesting to see how everyone had a similar approach to resolving the problem and used different tools to get there. Some were able to create concise solutions that made use of system methods while others ended up replicating the same work or something very similar. Great example of where it pays to know (or, minimally know they exist) some of the more rarely used methods in the documentation.

Thanks to everyone who has participated so far and for those that are checking these answers out now and think they can do better!  Keep the submissions coming and we hope you're enjoying these challenges!

Link:  Lab Coat Challenges

Starter Code



Asserts for all code




@PramForce




@melmoussaoui




@DeborahOrth




@DouglasCAyers




@@scottpelak




@MichaelWelburn




@venky_mass




@@SF_Tidbits






@anonymous






@nickforce




@CloudAnatomy




@michaelbsalty













Sep 1, 2015

Lab Coat Challenges: Challenge #4 Now Available

Challenge 4: Get Crackin'

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

The last challenge had you thinking with a particular mindset.  This week is a bit of a continuation of that.

Clue
k == a

Objective
Programmatically determine how k relates to a and use that knowledge to decrypt the following string:

Click here for the string!


















Aug 25, 2015

Lab Coat Coat Challenges: Challenge #2 Responses!


Responses are in!


Just like our first challenge, the second had a lot of great submissions. A few common approaches early in the week and a few revisions later after we issued a "Can you do it in a single FOR loop" sub-challenge.

Again - If you haven't had a chance to submit your answer for this challenge OR you think you can improve upon the answers below, please do!


@EricFishmanSF



@melmoussaoui



@DouglasCAyers



Anonymous



@tet3



@debdeepSFDC



@DeborahOrth



@kirkevonphilly








Aug 23, 2015

Lab Coat Challenges: Challenge #3 Now Available


Challenge 3: As Easy as A to B

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

It's back to school already for a lot of young developers out there.  We though this would help them recall some of that knowledge that might have been lost over the summer. 

A... B... shoot, what comes next?

This week's challenge is all about finding the easiest way to increment characters.  How do you increment a string that is set to "A" to "B?"  How about "S" to "T" and so on?

If only if it were as simple as "A" + 1.  Or is it?

In the sample code, you'll be providing the body of a method that accepts two parameters:
  • Letter - a string of a single letter that you'll be incrementing
  • Step - an integer to control how far many steps the starting letter should be shifted.
Up to the challenge?  Review the rules, full details and starter code here!






Aug 19, 2015

Lab Coat Coat Challenges: Challenge #1 Responses!


Responses are in for our first Lab Coat Challenge!

We had some great responses over the last week from several Salesforce devs!  If you haven't had a chance to submit your answer for this challenge OR you think you can improve upon the answers below, please do!




While all technically were valid answers, submissions generally fell into a few camps; those with structure that could be used and extended beyond the example strings and collections provided, those that would only work with the examples given, and those just being..."slick."  We'll call it "slick" and leave the interpretation to you...

Early in the week, no two answers were the same.  By the end of the week, we had several that made use of the list.addAll() method.  Others techniques included various ways of pre-populating lists and even various string manipulations.


All code started with the following...



All code was verified using...



So let's take a look at some of the responses!

Note:  Some code might have been modified up for readability.

Anonymous



Anonymous



@DouglasCAyers



Anonymous



@nitingupta9927



Dan Kelner



@EricFishmanSF



@debdeepsfdc



CRM Science Responses

@kirkevonphilly

When we started preparing these challenges, I wanted to be sure to be able to provide an answer for each. So how did I approach it? Dynamically, of course!



@mikekatulka



Tom Miller







Aug 16, 2015

Lab Coat Challenges: Challenge #2 Now Available


Challenge 2: Reversing Text

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

Challenge #2 is a simple task!  Turn "eeS uoy ta !ecrofmaerD" into "See you at Dreamforce!"  See what we did there?   How few statements do you need?

Up to the challenge?  Review the rules, full details and starter code here!





Aug 7, 2015

Lab Coat Challenges: Challenge #1 is Up!

Visit our website


Introducing the CRM Science Lab Coat Challenges!




Hey developers!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

Challenge #1 is all about working with collections and doing so as efficiently as possible.  The gist is you have a few strings, few lists of strings, few sets of strings, and it's up to you to merge them all down into a single list of strings, using as little code as possible.

Up to the challenge?  Get the full details here!








Jun 27, 2015

How to Abort a Scheduled / Queued Apex Job by Name

https://www.crmscience.com/lab-coat-lessons

For the advanced salesforce developers out there.... in the past (before Winter 14 release) there was no way to query for a Scheduled, Future, or Batch job by the name that was given to it. You had to track the ID of the job as the job was being created and store this into a custom object or setting for future reference.

Thanks to a feature from Winter 14 which stemmed from this idea, you can easily query the CronTrigger object filtered by the job name.  Remember to increase your API version in your class if this does not work.

Now we can query for the apex job by name and perform a system.abortjob with confidence that we have the correct job.

Here is a nice block of code that can be used in your application or something to keep handy for an Execute Anyonymous situation.



Jun 9, 2015

This change set requires the "##.#" or later platform version

Overview
It's that time of the year again (one of three times, actually), where you might be attempting to make some fixes in a sandbox that has already been upgraded to the next release and uploading a Change Set from that org to Production where the next release hasn't been applied yet.

Error
This change set requires the "##.#" or later platform version

Scenario
  • Sandbox 1: Summer '15
  • Production: Spring '15

Resolution
By chance, did you get to this point by following a normal deployment pattern? You know, where you deploy from a developer sandbox to a full sandbox and are now ready to deploy to Production? 

Chances are, the full sandbox you deployed to was also upgraded to the next release. You probably already know that upon upload, a Change Set's components are locked down. But did you also know that the API version of that Change Set is set and locked based on the target org's API?




This means that when you uploaded from your developer sandbox to the full sandbox, the Change Set was set to the latest API version and is now locked to it. When you attempt to upload this same Change Set to production, you get the "This change set requires..." error message.

Out of luck? Nope! Just "Clone" the Change Set and re-upload.



When you create a new Change Set by cloning, you're creating a new instance of the Change Set with all the original components and is unlocked so new components can be added.  At this point, the API number has yet to be set as well.

This time, don't upload to a sandbox first; upload it directly to Production so the Production org's API number is set on the Change Set and the upload is allowed.