One flow to rule them all.

Standard
One ring

Photo taken somewhere in SFDC HQ.

Recently, I found myself in a situation where I had a specific thing (Top Secret, Sorry!) I wanted my flow to do, but across multiple types of objects. As I built out my flow, I kept thinking, how can I build this so that it is a smarter flow? One that can accept multiple starting points? Well, to quote the announcer voice, “We have the technology, we the ability…”

But, let’s scooby doo intro back to the start…here is what I know:

  • The functionality I wanted to build involves doing a similar action against a lead, account and opportunity.
  • I can use a workflow to kick off this change
  • I can use a flow trigger to kick off the flow

Let’s start with the flow. What I actually did is not as important and the method, so a neat screen shot is not needed! The key piece here is that I have an input /output variable named “VarPassedRecordID”. Beyond that, really the ONLY other piece of the puzzle is a couple of decision points, one for each record. The decisions are all looking at the prefix of “VarPassedRecordID”. If the prefix of the ID matches the criteria, then the routing goes to the designated action

Update Account.

Decisions with Actions

As a side note, I have started using this methodology in my criteria’s when I look for query results instead of looking for nulls.

The next step is the workflow’s. In my case, there are three workflows and each workflow kicks off a flow trigger. If you do not have flow triggers, go get them enabled! Flow triggers are great for these small jobs, though you could do this with the process builder as well…The flow triggers are themselves unremarkable. The only thing they are doing is passing the record ID over to the flows…wow, reading this one over, this is really boring functionality. Seriously, this is like trying to make a pair of needle nose pliers or a shop light sound exciting! However, like needle nose pliers or a good shop light, this is a very good piece of functionality to know about. You can add new object types in very easily and with out creating more and more flows.

Recap? Sure, why not, this blog post is seriously shorter than half my papers I wrote in High School…Size 12 font! Double Space! Times New Roman! Business, Business Numbers! Is it working?

tumblr_nm4d2wZ7Go1r7r8d2o1_500

  1. The workflow runs if the criteria is met
  2. The workflow kicks off a flow trigger, which passes over the record ID to the flow
  3. The flow analyzes that data, and based on the prefix, directs the data down the right path

The only real “gotcha” to be aware of is that if you are using custom object, the record ID’s might have different prefixes based on your environments. You will especially find this true if you are migrating up the custom objects.

 

As always, let me know if there are any questions, comments or suggestions!

 

Andrew

 

Random Number Follow Up

Standard

Back in the day, when this was just blog was just a baby blog, I wrote a post on generating random numbers in Salesforce.

Even though I wrote this function as a learning experience, I have received quite a few comments from folks who actually have a work need for this function.

The most recent was from Daniel, who wrote that his organization has three inventory groups, A, B and C. All groups get audited once per year. C Parts are counted once per year, B parts are counted twice per year. A parts are different though. A parts are selected at random for counting once per month.

So, there you have it! A real life example of why the random function should be included in the Salesforce formula library! <<VOTE HERE>>

So, I now dedicate the rest of this blog post to Daniel!

First things first, I created a new object called “Spacely Sprockets”. I have a text box for inventory grouping, where I have noted if the record is in A, B or C.

Next, I created three formula fields, “String Build”, “Dice Roll” and “Build Audit Grouping”.

The “String Build” formula is the same as my last post, and uses the “now” function to build out a string.

sqrt(

(value(

(left(right(text(now()),6),2))&

text(DAY(DATEVALUE(now())))&

text(Month(DATEVALUE(now())))&

text(Year(DATEVALUE(now())))&

(left(right(text(now()),9),2)))

)/100
)

The “Dice Roll” formula is a bit different than before. I found a couple of neat posts written after my original post that used the MOD function. This one is a bit deep, but check it out!

if(right(Name,2)=”00″,1,mod(mod(value(right(Name,2))*3,101)-1,10)+1)

 

I am using the right two digits of the autonumber of the record as my seed, with a correction on for AutoNumbers that end with “00”. Basically, I dump those to the dice roll of 1. This was done for the sake of time, but you could get fancier by moving these orphans to perhaps the month? Up to you!

The last formula is the “Build Audit Group” formula. What this one is going to do is use the MID function to locate a single number out of the string. To find where that number is, it is going to use the dice roll value ( 1 to 10) + the right digit of the autonumber (1 to 9) to determine which group (0 to 9) the record belongs. The reason I am using the autonumber as well is to further randomize things.

mid(text(String_Build__c),(Dice_Roll__c+value(right(Name,1))),1)

The results look promising, but I really need to emphasize that you more than likely, you will need to tweek this method! Even as I was building the function for this blog, I was finding little ways in which to improve things…but, since I have not found a good need for this yet (beside my rock / paper / scissors / lizard / spock game) I didn’t plan on spending a bunch of time refining it.

OK…is everyone still with me? Alrighty, let us take a look at some results. I have been running a simple matrix report on my Spacely Sprockets data that shows the audit group with the dice roll. I have run it 9 times over the last couple of days. As mentioned, the results are promising…not perfect yet for a robust random audit feature, but not bad.

The chart below definetely shows some preference, but a large part of this is related to the bug where the audit grouping is a “.” (Period) instead of a number. My guess is that if that bug was eliminated, the numbers would continue to flatten.random number results

Here is a table with the selection totals by audit grouping:

by group

This further firmed up my belief that if the period bug was eliminated the findings would be closer.

Hope this helps!

 

Andrew

 

 

Dynamic Screens using Visualforce and Flows

Standard

 

Oh boy, do I have something real nice for you all today!

Real nice.jpg

Something Real Nice!

Let’s say, you find myself in the world of action adventure blockbuster “Pacific Rim”. You are tracking Kaiju in an object called “Kaiju” and and tracking Jaegers with an object called “Jaeger”. From the detail page of Kaiju, I create a new detail button called “Dispatch Jaeger” that runs a flow by calling a Visualforce page. I know this is not typical, but stick with me! This flow associates the selected Jaeger to the Kaiju so then the whupping can commence!

Kaiju vs Jaeger

That works pretty well, but a user will always have to be on a Kaiju detail page to dispatch a Jaeger, so it might be good to put something on the home page that allows someone to either dispatch a Jaeger on an existing Kaiju OR create a new Kaiju and Dispatch a Jaeger all at once.

The first place I went is the google verse because I thought I would just create a small Visualforce page with an input box on do some sort of URL hack to get it to push a value to the already created Visualforce page that launches my flow. Turns out, there is really no such thing as “small” when it comes to this type of stuff. Most of the articles I read involved some sort of controller, so my overhead went pretty quickly from one Visualforce page to Visualforce page + controller + tester.

Back to the drawing board I went!

2015-12-09 15_45_16-pacific rim whiteboard - Google Search.png

I remembered some early work I did with flows where I used a decision element as my starting point, which would then direct a user to certain pages. I decided to explore the option of using this, and it worked!

Here is what I did! I modified my dispatch Jaeger flow so that the starting element is a decision.

Flow Overview

Starting Decision

This decision checks to see if KaijuId is being passed over from the Visualforce page, which it would be if you were launching it from Kaiju Detail. If this value does not start with the prefix for the Kaiju record (This works WAAAY better than checking for null or not null), it redirects to the newly created “quick dispatch” screen element.

I added my Visualforce page to my home screen and boom, my flow correctly presented me with the quick create screen!Home Page

However, I still needed the ability to create a dispatch from the detail screen, so let’s click the button and see what happens!

Dispatch from Record Yep, the flow determines that I am running a dispatch from a record detail and points me to the right screen!

To sum it up…I was able to with Zero Extra Code, modify my flow so that two different screens are presented to the user based on if they were dispatching a Jaeger from a specific Kaiju, or were having to dispatch a Jaeger from the home page via a quick create function.

Dispatch jaeger VF code
You might also be wondering why I am using a visualforce page? Well, if you want to run flows in a community, you have to wrap that flow in a visualforce page…That being said, you can totally do this same type of thing with a URL launched flow too…the functionality is really the same with the novelty part of this being that it works within Visualforce.

So, that wraps this post up! Thanks for checking it, comments / questions are always appreciated.
Also, quick note, I will be at the Salesforce World Tour in Seattle on the 17th. I would be more than happy to talk about flows or other Salesforce awesomeness, just look for this guy:

Salesforce in Seattle!

I am smiling because I support Salesforce

Attaching a copy of an email alert in Salesforce

Standard

How long has it been? A long freaking time!
Long timeBetween summer vacations, coaching soccer and cub scouts, there has not been much idle time for this boy to blog, which stinks because there has been so much fun stuff figured out!

But, here I am, eating a turkey sammich, listing to some EDM on Slacker Radio and trying to get a blog post cranked out for you all.

What I am going to blog about is an annoyance that has been going on for quite some time… the issue of workflow email alerts. In fact, this idea is over 5 years old!

See, when you build out an email alert and it fires…well…it just fires. You can do a work around that involves carbon copys to an email to salesforce box or creating activities, but those workarounds are either not scaleable or they don’t give you much more information than “this email was sent!”.

But, I did find a work around that is scalable using my favoritest thing ever, flows*. Now, did you see that little thing there? That Asterix? Yep, that is there for a reason. It is there because I wrote this out using flow triggers. I am sure you can do this with process builder, but I am just documenting the flow trigger function here. I like process builder, but in this case, I just need to crank something out quick, so I am using triggers.

The “Too Long; didn’t read” version is this. I created a flow that runs via the workflow (remember, I am using flow triggers!). When that flow trigger runs, it will do two things. It will send off the email alert AND create an emailmessage record. Yeppers, I said create an emailmessage. What I have found is that within salesforce you can create an email record through a flow and it will happily sit there. The trick is that you will need to pass the record ID from where you are starting and use that ID for the “parent ID” field on the emailmessage record.

This is a good jumping off point if you want to venture forth and tinker around yourself. For those of you that want more details, here ya go!

My assumptions at this point are that you are comfortable creating your own method of running this flow. As long as you can pass variables over from the record, you should be good to go. This flow only has two elements. The email alert (which is already built) and the record create for the email message. There are a bunch of things you can build out when you create the email message, but I am just going to cover the basics.

  • Parent ID – this should be the record you want this emailmessage living under. In my case, it was, well, case.
  • Status – Status is a funny one. It is displayed in plain English but the value is actually numeric. In my case, I am recording a copy of a sent email, so I used a status of 3, which is “sent”.
  • EmailMessageBody – An interesting thing about this method is how the text is displayed. You will actually be creating the emailmessage.body by using the field “HTMLbody” and to make it so the text looks nice, you will need to do the following:
  • Create a text template called “LineBreak”. This text template will just have the HTML value for break “<BR>”

Line break

  • Create a text template called “Email body”. Enter your data and insert the text template “linebreak” wherever there should be a line break. If you need to get values from the parent record, insert them here. I choose to pass them all over via the flow trigger, but you could just as easily do it with a requrery.

Linebreak being used

The end result is that the emailmessage you created via the flow will have a similar look / feel to the email that was sent out via the alert. Actually, it will look way more like the Text version, but really the point is to have this copy not so much to look pretty.

As I said before, I will leave the method of running this flow up to you, so let’s talk about the results.

By doing this, I was able to get a copy of the alert email attached to the parent. I was then able to remove the activity creation on the workflow since that was how we were noting that an email was sent out. The email copy is an actual copy, so we know what was sent out, which you couldn’t do through the activity. As an added benefit, running this via the flow allowed me to do some extra shenanigans that you really cannot do through a workflow, like running queries on other objects and adding them to the email.

The last benefit is crazy obvious, this is a LOW maintenance function. If a new value is added to the email alert, I (or another admin) just needs to add it to the record creation function…no dev time needed!

As always, let me know if there are questions / comments

 

andrew

 

 

Calculating number of months between two dates in Salesforce

Standard

It has been a long time since I blogged about a formula. Not that I haven’t built any, just nothing really new and exciting…until now that is!

excited

The problem under consideration is calculating the number of months between two dates. Before you go all “Phhhh, that is cake” take another think on this! See, it is easy for a human. We know that there are 12 months in a year, but to get a machine to do this automagically, well, it is not so straight forward. Getting days is easy (Date2 – Date1) and getting years even wouldn’t be too bad (year(date2)-year(date1)) but month is kind of an oddity, because you can’t just say Month(date2)-Month(date1) because the month is just this lonely little digit out there…you need the year to give context. But, how do you express that weirdness in a formula? Well, read on my friends.

My first instinct was to go with the number of days divided by 30, but about a nano second after that popped in my head, I remembered the whole “odd number of days in a month” thing. Not to mention, freaking leap years!

So, back to the drawing board I went…and I thought and I sketched some ideas out and finally, I hit upon the solution! I needed to not think about this as one problem, but three separate math problems.

To start with, here are my dates:

5/1/2015 and 6/23/2018

First thing, in the oldest date, we need to calculate the number of months left in that dates year…

Example – if the date is 5/1/2015, the value here would be 12 – 5 , which equals 7

Second, in the newest date, we need to calculate the number of months that have already passed…

Example – if the date is 6/23/2018, the value would be 6

Third, we figure out how many FULL years are between the newest year and next oldest year and we multiply that by 12. Since we have already considered the number of months for the oldest date, we need to add 1 to the year. We then subtract that number from the year value of the newest date.

Example – the next year for the oldest date is 2016. The newest year is 2018. The difference is 2 full years or (2*12) = 24.

Now, you sum all three values together like so:

7 (Number of Months Left in Oldest Date) + 6 (Number of Months that have passed in Newest Date)+(2*12(Number of Full Years times 12)) = 37 months.

Of course, the formula doesn’t actually look this nice…the formula itself is, well, awesomely gnarly!gnarly

Feel free to use, just replace “Your End Date” with whatever end date you want and “Your Start Date” with whatever start date you want!

/*checks first if the start / end dates are in the same year. If this is true, then the value should just be the month – month*/

if(year(Your_End_Date)-year(Your_Start_Date)=0,month(Your_End_date)-month(Your_Start_Date),

/*If this is not the case, are they at least 1 full calendar year apart? If this is the case, then do the big calc*/

if((year(Your_End_date)-(year(Your_Start_Date)+1))>=1,

/*Value if True*/

(

((year(Your_End_date))-(year(Your_Start_Date)+1))*12)+

((12-month(Your_Start_Date))+month(Your_End_date)),

/*If the years are not more than 1 apart, do this calc instead*/

(12-month(Your_Start_Date))+month(Your_End_date)))

An awesome variation of this is where you substitute “start date” with “today()”. This will give you a dynamic countdown of the months left between “today()” and whatever the end date is, as long as your start date is before “today”!!!

So, where would you use this? I built this out for a specific request, but I could imagine a couple other purposes:

  • Depreciation of a value
  • Territory Realignment that is weighted for time remaining in a date range
  • Reporting on the number of months between a created date and a closed date

Any other ideas? Thoughts?

Let me know!

andrew

The hot fudge for your visual flow sundae

Standard

Flows really are a ground breaking piece of technology.

were not worthy

It was evident last year at DF14 by how often there were talked about. More stuff is being added every release and there is a great big community of users!

UI based flows are awesome for internal user, just pop the URL into a button and instant awesome! A question that is constantly being asked is, how do I get the pop up window to go away”

See, when you launch the UI version of the flow, it does it’s merry little thing and then takes you back to the start, which is not always ideal! Being that we are all really clever folks in this community, there are a bunch of ways around this, but a lot of them require visualforce / apex or a URL hack…but not many of them actually address the needs I had:

  • I need this to run with in a community
  • I would like the window to close once the flow is completed

First things first, we need the flow to run in a community. According to page 115 of the Visual Workflow Guide:

“Enable external users to run your flow by adding the flow to a Visualforce page and distributing that page through a Force.com site, Customer Portal, or Partner Portal.”

OK, no big deal there. This topic has been covered extensively on this blog and others! As a side note, this is how you get flows playing nicely with Salesforce1, so head over here to learn more…I will wait!

Ah, you are back! Now that we have a flow that will run on communities or internally. How the heck do we get the flow to close out the window? Well, after googling various iterations of “closing visualforce window” I finally just decided to google something like “close browser window javascript” (This was after googling “Moscow Mule Recipes”).

I wish this just came from one source, but I was really using the google hive mind that day! What I ended up doing is using some javascript in a visualforce page called “ForceClose”:

<apex:page showChat=”false” showHeader=”false” sidebar=”false” applyBodyTag=”false” applyHtmlTag=”false”>
<html>
<head>
<title>ESCAPE</title>
<script>
function closeWindow() {
window.open(”,’_parent’,”);
window.close();
}
</script>
</head>
<body onload=”closeWindow()”>

</body>
</html>
</apex:page>

NOTE! If this code looks familiar to someone, please let me know so I can give you a hat tip from little corner of the web!
NOTE + 1! I still have my #ClicksNotCode card, so I would imagine this is not near good code!

Now I have a flow that runs in a Visualforce page AND a Visualforce page that should (in theory) close itself. It is time to…wait, I wish this step could be more dramatic…maybe you could read this in a monster truck voice? Just in your head so you are not disturbing your neighbor! OK, carry on…join the two pages together! Just set your finish location on your flow visualforce page to be the forceclose page!Add Finish Location

And, that is that! So, how does it work? Well, pretty darn good! The super sweet thing though is that this is reusable! I now used the “ForceClose” page 5 or 6 times in various flows, and that is really nice!

As always, thanks for reading the SFDCinSEA blog! If you have any questions or comments, let me know!

Automagically create tasks from templates in Salesforce!

Standard

If you are like me, everyday upon waking up, you are craving coffee. This craving requires action and also requires a set number of steps that will repeated as long as this craving is happening (Hopefully, forever and ever). If I were to map this out, it might look like this:Tasks to Coffee

The act of me waking up will prompt a series of tasks, and this is something that is repeatable EVERY TIME.

Now, apply this to your users. How often will the user be DOING something that requires them to CREATE a task or series of tasks? Here are a few examples I could think of:

  • After closing a deal, follow up tasks are scheduled for 30 / 60 / 90 days out
  • After contacting a lead, follow up tasks are scheduled
  • After losing a deal, create a set up follow up tasks

The key to this exercise is identifying ACTIONS that will require a set of tasks to be created. This is the challenge that I decided to take on with my Salesforce BFF visual flow and my Salesforce Frenemy Process Builder. The idea was that when a case meets a certain criteria, a series of tasks will be created…and is this wasn’t challenging enough, I decided to kick it up a notch and design the functionality in such a way that the tasks are not hard coded but actually templatized.

Here are the ingredients to this functionality:

  • “templitized” tasks
  • A flow
  • A process (though, you could use a flow trigger as well)

At a high level, what will happen is that the flow is kicked off via the process (or trigger). The flow does a query of all tasks and ONLY pulls those that meet our templatized criteria. These are then used as templates for the creation of new tasks. The example below is how I built this out so that a series of tasks are created when I mark a case as “Ready for Coffee”.

Enough talking! Release the Screen Shots!

Release the Screen Shots

Step 1 – Create a “templatized” task

In this case, I note that the task is a template by placing a flag on the subject and setting the task status to completed. By setting the status to completed, you can keep the task from staying open and visible on the users home page. In the example I am building out, I am looking for a subject that ends with “!MakeMeCoffee”.

Task Template XLS

I am using the connector for this because…well…it works and I didn’t want to do it by hand!

Step 2 – Create your flow

The basics of the flow is that there is a fast look up to find your templatized tasks and put them into a Sobject Collection. This collection is then looped through with your regular loop de loop, which builds out the set of tasks that will be created. Be sure to build out a formula for the subject field that strips away the template flags,

Build Task Subject

else, well, you might end up with a lot of stuff!

Flow Magic

As usual, when I built out my flow, I built out one version that is driven off of the UI (pictured below). This way, I can do rapid testing without activating anything. After things are 90% happy, I will remove UI elements and save it as a new flow.

Step 3 – Create your process

Process builder is my frenemy…I see the potential, but am still really sore over loosing flow triggers. But, the cool thing is that we have folks out there in the Upper Echelons of Salesforce looking at our comments and reading our blogs and they are making changes and I am excited for where process builder is going! Soapbox aside, I created a process for case and set the criteria.

Criteria Logic - Process Builder

The ONLY thing this process is doing is calling the flow and passing over just enough information to run. In the past when I have used flow triggers, I tended to push over more information, but since process builder requires activate / clone / activate cycle if something goes ker-plewy (for the record, I did this cycle 7(!) times for this demo!), I have switched over to just pushing over the minimum as a variable.

OK, so the work is done, you are all set…Let’s see how this works!

Now, for the proof.

I have my case created, and I am going to check the box that signals that I would like some coffee.Ready...

As you can see, tasks are now created associated with the case.Go!

To emphasize again, the power of the template is that if I (as a user, not a system admin) wanted to change something about the tasks are created, I can do so on my own and not have to wait for a system admin. Another great benefit for the admin / developer is that nothing is hard coded except for template criteria…and even that could be made more dynamic to handle further scenarios.

Further mind blowing awesomeness is that this is NOT just for tasks on cases…it could be anywhere…or even applied to other objects!

Questions / Comments / Buy me a coffee?

Andrew