Fuzzy Searching in Salesforce Flows

Standard

Salesforce flows are a magical thing, like good coffee at work and unicorns.

coffee unicorn.jpg

This is how I want my coffee delivered.

 

I have come to realize that there are limits to even the most magical things (BOOO!).

The limitation I have found in flows is around how you search for records…but, let me be clear, it really isn’t a big deal. For most people, finding records using the typical “equals”, “contains”, “starts with” and “ends with” functions will work just fine. I however, found myself going down a path where that wasn’t going to quite cut it. The challenge is how to search on a text input in a manner that is more google like. I don’t know what the kids now a days call it, but back in my day, we might call if “Fuzzy Matching”.

Fozzie_bear.png

Fuzzy, Not Fozzie!

For example, let’s revisit my Jaeger Dispatching System (Special Note, Pacific Rim 2 is scheduled). This system uses dynamic drop downs for the Jaegers, but, what happens when you have a bunch of Jaegers’?  You can build out a record search based on a text box, but, as mentioned before, you are limited to “equals”, “contains”, “starts with” and “ends with” functions. At this point, you might be saying, fine, just use a “contains” operator…and that would work, except what happens when the user spells something wrong? Contains is just two wild cards, so if you entered in “Dangur” instead of “Danger” you would not get a hit.

 

What happened next is pretty funny. I started thinking about how there are patterns in words…and then started thinking about how the pairs of letters could work. Spoiler alert, it totally worked. I proved it in Excel by just using a vlookup and some formulas, so I got pretty excited. It was then that I googled this matching pairs thing and found out that yep, some one wrote about all the fancy math behind it.

http://www.catalysoft.com/articles/StrikeAMatch.html

So, after building out the proof in Excel that this would work, I set about trying to get this to work in Salesforce…specifically a flow. I want to be able to enter in some characters into a text box and see returned results based on how well they matched my search term.

The first thing I did is create a field that removes the spaces from the Jaegers’ names and made them lower case. I don’t want it being “Cherno Alpha”, I wanted “chernoalpha”. This is done via formula field. If doing this in real life, I would build out my formula to also remove punctuation, but this is just for my Jaeger dispatch and my blog, so I am just removing spaces.

Thus, concludes the non flow part of this blog…what follows next is like 100% awesome, you have been warned.

TAKETHISCAT.jpg

Woot! FINALLY got to use this meme!

The first couple things are pretty basic, I have a start screen that has a text box. Next, I have a fast lookup on my Jaeger object. This gets all the Jaegers and puts them all in a collection. Next up is my loop, where I go through each Jaeger record. The only “gotcha” is that when you do the fastlookup, you need to bring over your formatted text from the record. Screen shots of this would be pretty boring, so here is a picture of all the giant robot toys.Jaeger Toys.jpg

Within the loop, I start with two assignments that copy the formatted Jaeger Name (no spaces) and the search string to variables.
I am going to use these variables for the rest of the functions, including the formulas. I take the search string that was entered and format it up.  I remove the spaces, count how many pairs I have and if the value has a remainder, I also remove the last character. I do this because otherwise the matched pair logic would be searching on a single digit, which would skew the results. The formula also checks if the search string is just 3 char, and if it is, it will treat these three char as one “pair”. Pictures and Text!

Formatted Search String

if(len(substitute({!Search_String},” “,””))<>3,
if(
mod(len(substitute({!Search_String},” “,””)),2)<>0,
left(substitute({!Search_String},” “,””),len(substitute({!Search_String},” “,””))-1),
substitute({!Search_String},” “,””)),substitute({!Search_String},” “,””))

Now I have to compare my first matched pair to the formatted name. of the search string that was formatted. I use a formula to get my matched pair:assignment - formatted search string.png

if(len(substitute({!Search_String},” “,””))<>3,
lower(left({!varSearchStringUseCopy},2)),lower(left({!varSearchStringUseCopy},3)))

 

The flow will next do a name check via the decision function. If the Formatted Jaeger Name contains the current matched pair, the flow adds a value of 1 to the counter variable and adds the current pair to a variable that will show the matches and the ID of the current record to another variable. Ugh, that was hard to read, here is a picture:assignment - match found

If the pair is NOT a match, well, I don’t really do anything with it but you might want to shove it to a debug variable. In fact, if you are starting this from scratch, I would HIGHLY suggest you do this!

Next up is yet another assignment, this time though, we are removing the pair was just searched on. This is done with, you guessed it, a formula:

if(len(substitute({!Search_String},” “,””))<>3,
substitute({!varSearchStringUseCopy},left({!varSearchStringUseCopy},2),””),substitute({!varSearchStringUseCopy},left({!varSearchStringUseCopy},3),””))

remove search string

Once that is completed, we check to see if there are more pairs to check. This is done by looking at the number of pairs left after the current pair is removed. This is in a formula I like to call “DisappearingSearchString”:

len({!varSearchStringUseCopy})

The whole process looks like this:

match process

If all the pairs have been used, the flow then checks to see if there were any matches with a decision point on the counter variable. If yes, then we add the matching data into a variable and then start the loop all over again. Because we will want to display some results in a table like format, be sure to append a text template that has a line break at the end of the string. To do this, create a text template with <br> in it.

build out result line.png

One of the things I really wanted was a way to see how many of the pairs were found in a given record. I do this with this formula:

({!varTripCount}/{!frmSearchStringPairs})*100

 

Before the loop starts all over again, any used variables are reset:

clear counters.png

So, enough talk! Let’s see how this works! For comparison purposes, I put in an alternate lookup that will use the “Contains” search function of what was entered in the input.

I also added more Jaegers, 8 in total!

Jaeger List.png

boom

 

First search string is going to be “Eureka”:

Eureka.png

and here are the results:Search Results - Eureka.png

The “Contains” function did what I expected and returned two records, “Striker Eureka” and “Eureka Smack”. However, it did not find “Striker Eurek”, but the matched pairs function did!

Let’s try this on another scenario. Suppose there is someone new in the Jaeger Dispatching Center and they forgot that it is “Cherno Alpha” and they enter in “Alpha Cherno”.

Search String.png

The “contains” search function would literally return ZERO results, whereas the matched pairs function would show an 80% match with Cherno Alpha.Results - Cherno Alpha.png

So, there you have it. With a bit of work, you can do fozzie…err…fuzzy search results with in a flow with Zero coding!

As always, if you have any questions, comments, or suggestions, please let me know!

Andrew

Advertisement

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

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!

Cleaner Page Layouts using Flows and Formulas (1 of 3)

Standard

Back in the day, when I was just a transfer student at Everett Community College, “one week” was a hit single and I was a newbie coder taking visual basic.

(Your welcome for this ear worm)

During this class, we had a discussion on page layouts, that went a little something like this:

If you design a layout that has a bad tab order, and it reduces the speed of a transaction by one second, is it a big deal? Well, consider it this way: If your software is bought by a million people, and they can complete 500 transactions a day, your one second reduction of efficiency is costing the consumer 500000000 seconds per day…which is 8,333,333 minutes or 138,888 hours. If the average wage of those users is ten dollars an hour, your one second in efficiency now has cost 1.3million dollars per day.

Not even a Lego Calculator could make that discussion cool

With guilt trip thusly set to “argh”, I focused my efforts on UI design and making things work efficiently. Even now, I can remember the tab order of one of my first CRM’s I worked on…because it was out of order.

The stakes have changed since I was taking Visual Basic. I (we) support sales, and lost productivity is not simply about lost time, but about what your sales teams COULD have been doing. The math is pretty easy…and pretty scary:

Time spent clicking / scrolling / using salesforce in an inefficient manner

X by Number of times

X by Number of Users

X by days in year

= Time wasted = Money Lost = No free coffee

For the sake of this blog post, I am going to clean up the contact layout. I have sat with my users and estimated that they waste about 2 seconds every time they hit the layout  because of a section that Marketing has requested. This section consists of four check boxes, three text boxes and one URL field in a two column layout. This section was created for marketing and was placed near to the top of the layout in return for the data not being required. This section pushed a much more used section down below the scroll line (IE, users would have to scroll to see it). Marketing has given the OK on making this section not visible as long as there is some visual refernce to these fields still on the page layout.

A user will typically hit the contact layout 25 times per day and I have 25 users. If I can compact the layout, I should be able to reduce scroll time by about half, which should save about 45 (sales) hours per year. Notice, I didn’t just say hours, I said sales hours. Sure, saving 45 regular hours might not be much in the whole scheme of things, but sales hours is like a force multiplier. If you enabled your sales teams to have even a few more minutes per week, they can make a few more calls, make a few more emails, make a few more dollars.

Take a minute to enjoy this worn out cat.

Phew

I am beat just writing about this!

I am going to break this whole thing out into three distinct chunks:

1)      Create the Summarizing Formulas (In this blog)

2)      Create the Visual Prompts (Next Blog)

3)      Make Data Entry awesome with Flows (Next Next Blog)

Summarizing Formulas

Personally, I tend to write smaller, nested formulas that analyze bits and pieces of data. This makes it a bit easier (in my opinion) to write that final formula that presents the results to the user. While you could probably write this all in one huge formula, for the sake of troubleshooting and scalability, I am going to create the following fields:

1)      Create a formula to look at the 3 text fields (Return Type is Text)

Text(

if(len(Test_Text_1__c)>0,1,0)+

if(len(Test_Text_2__c)>0,1,0)+

if(len(Test_Text_3__c)>0,1,0))&” out of 3 populated; ”

Text Box Formula

2)      Create a formula to look at the URL field (Return Type is Text)

if(len(Test_URL__c)>0,”URL Present”,”URL Not Present”)

URL Formula

3)      Create a formula to look at the check box fields (Return Type is Text)

Text(

if(Example_Check_Box1__c=TRUE,1,0)+

if(Example_Check_Box_2__c=TRUE,1,0)+

if(Example_Check_Box_3__c=TRUE,1,0)+

if(Example_Check_Box_4__c=TRUE,1,0))&” out of 4 set to True; “Check Box Formula

4)      Create a formula to aggregate the above

Check_Example_CheckBox__c &” “& Check_Test_Text__c &” “& Check_Test_URL__cAggregate Formula

The net result is a field that will present the user with data facts not data entry points. Aside from having a cleaner layout, I a firm believer that if presented with text, most humans brains at least acknowlege that text before moving on. By reducing the clutter, you are making your overall page layout less fatiguing.

End Result

Individual Results

In the next post, I am going to discuss how we are going to visually prompt the user to give us data, but until then consider the other benefits of this type of functionality:

1) You could use these fields in reports to give better summaries

2) You could write validation rules off of these formulas rather than the individual fields

3) You could write workflows off of these formulas

See you all next week, same BatTime, same BatChannel where I will show you all how to kick it up a notch and grab your users attention!

Kick it up a notch

You totally thought I was doing Batman pic, weren’t you?

Andrew

Cleaning the data that matters…and not all data matters!

Standard

In my previous post, I alluded to a list of 5 concepts that make data cleansing a bit easier (Not fun, not easy – peasy but easier). In this post, I am going to expand on the concepts of “Knowing your data” and “Classify your data”

It's about half the battle

GI Joe talks about knowing

.But, before we get into the methodology and the doing, let’s talk about tools used. We are actually only using two tool to build out the functionality found with in this post, reports and formulas. However, because the methodologies discussed below is different than most organizations approach to cleaning data (Ocean…Boiling) there will be work on you to get folks bought into the ideas of not just trying to clean everything. So, I guess if you want to get technical, a third tool is the soft grey matter inside your noggin!

First things first. To help me “Know” and “Classify” my data, I am going to write a report that has two bucket fields, “Customer” and “Pipeline”. The bucket fields are looking at two custom field that are rollups counting the number of booked opportunities and the number of open opportunities. These are my two primary classifications because I am going to use a combination of these two classifications to score the value of an account to my company.

1)      Non Customer, No Pipeline (Least Valuable)

2)      Non Customer, Pipeline

3)      Customer, No Pipeline

4)      Customer, Pipeline (Most Valuable)

My fictional org for “Kramerica” wants all 481k of their accounts cleaned. Before jumping in and just starting to cleanse, I set up a report that breaks down an account based on past purchases and pipeline. Just by using two bucket fields, I can see that 14,000 accounts (About 3%) that are high value (Customer with Pipeline), 13,000 (3%) are medium value (Non Customer with Pipeline) and 54,000 accounts (11%) that are medium value (Customer No Pipe or Non Customer Pipe). I have just reduced the pool of accounts that should be cleansed by nearly 83%.

Numbers don't lie

Dry those eyes, it is not as bad as it seems

Unfortunately, there is still a number that is not very friendly standing between us and Maragriatville.

Margaritaville is real, google maps told me!

Which is just outside of Dallas apparently.

So, we are going to take things up a notch and write a set of formulas that will score the data that is entered on our account records. The folks in charge of data management (and that might be you), decided that Address, Phone and Website were most important. Yeah, I didn’t put state / country, but that is because of the change making it a picklist field, and we will just assume Kramerica is using the picklists. I am going to end up creating four formula fields. Three formulas will look at the data contained in the three fields. The fourth field will sum the scores of the three fields and then based on the totals, grade the data “Good”, “Acceptable” and “Poor”. The formulas don’t have to be complex, even something basic like if(len(FIELD=0,1,0), which will check for the presence of any data in those fields.

Just the ones that matter

In this case, red is good because red = less work!

That was a fun diversion, now, go back to the original reports with primary / secondary classifications. We add in the data grading field. Now, you can see how many of your most valuable accounts actually need the most help. In the case of Kramerica, we want to distil down that 14% (68k accounts) even further so we can focus on valuable accounts that have a data score of zero (no values in any of the fields) or one (at least one field has some data in it). Applying the formulas and the buckets to my data set reduces the amount of accounts I need to look at from 54,000 to 18,000.

I think this deserves a quick, bullet pointed recap:

–        Initial data set, 480k accounts

–        Valuable Accounts:

o   Customer / Pipeline (Most) 14,000

o   Pipeline / Non Customer 13,000

o   Customer / No Pipeline 54,000

–        Data scoring of valuable accounts:

o   Zero data score = 5,000

o   One data score = 13,000

–        Reduced my “need to clean” by nearly 90+%

My SFDC admin is amazing

I get this way whenever I shake loose a bit more time in the day.

Yeah, that is pretty awesome. However, there is the question of what do to with all those “other” accounts. Here is where it goes from awesome to AWESOME (in a monster truck voice). Since you have already established what makes an account valuable, once an account meets a certain threshold (gets pipeline), you know that it then needs to be cleaned up…and of course, you know what needs to be cleaned up because you are already scoring it.

2014-06-01 20_51_21-awesome monster truck - Google Search

 

PS – For bonus points, create a nice email alert telling the reps their data is bad, and make it so it sends them that notice every time they edit the account OR opportunity…just put on a timer so it only sends once per day!

Don’t start cleansing data yet!

Standard

Data is a fickle beast.

One minute, you have amazing dashboards and reports… your finance nerds are seeing into the future with clarity a weather man can only wish to have…the next minute, you have gremlins everywhere causing chaos in the most basic of processes and you can only give accurate forecasts for five minutes in the past.

Don't feed data analysts after midnight!

All your data are belong to us!

I suspect this has been happening since mankind developed the first CRM, which was on Oracle Clay Tablets.

Oracle V1

You should see the servers needed for this!

Having been on many data cleansing projects in the past, with many more in my future, I decided to sketch out some ideas I have picked up along the way. Don’t worry, I will go back to my techie salesforce nerd stuff next week!

“It is a never ending story”

Cleansing data is not a project with a start and an end, it is a process that needs to be ongoing. If you have data coming in, you will have data that needs to be cleaned. Build it into your budget, chant the mantra, do whatever it takes, but embrace the fact that as long as you are around any CRM you will be doing data clean up.

“Business Involvement”

Even though dirty data and data cleansing will never go away, it will become a smaller task once you get your users sold on the idea of clean data. At the very least, you need your users to care about the system at the best they will become advocates of clean data. Boeing used to have a program called “FOD FREE”. FOD is “Foreign Object Damage” and it prompted their employees to be active in keeping the work environment clean. It was a huge success through marketing and  engagement, AKA, Business Involvement.

“Clean with a Purpose”

There are two methods to getting business involvement in data cleansing, carrot and stick. Personally, I prefer the carrot approach. Know why you are doing it, and be able to explain that to the business. Tell them in “What’s In It For Me” (WIFM) terminology why their data is changing and what outcomes they can expect. Have them involved in any process modifications or validation rule building. If you get them at least interested in clean data the process will be much less contentious.

“Know your Data”

Seriously, run some DANG reports. Know the numbers because someone will ask. Know the up and downstream impacts of dirty data. Know use cases. Have a really nice power point set explaining this things, and gear the presentations to different user levels. If you do not  know your data, how can you clean it???

On a side note, I swear by “You suck at powerpoint” as a great learning aid around presentations!

“Classify your Data”

Classifying data is just chunking up your data into sound bite groupings. The key here is “Sound Bite”. You can say something awesome like “Customers with an account that has at least 3 contacts that all have been sent an email in the past three years”, but after the first couple words, all anyone will hear is “blah blah blah”. Instead, have sound bite ready classifications. Thinking in “Sound Bite” terms will also help with reporting and formula writing, covered next week!

Here are some suggestions for accounts:

Primary = Customer, Non Customer

Secondary = Active (Open Pipeline), Non Active (No Pipeline)

Tertiary = Marketable (Contacts with Email), Non Marketable (Contacts without Email)

It’s looking a lot like Christmas (Sigh)

What really gets me excited about classifications is that it helps you NOT boil the ocean. It is not unrealistic to have hundreds of thousands of account records, and if you were to set about trying to clean them ALL, you would be wasting time and money on records that really are the equivalent to that fruitcake you got last year. It is just taking up space, but you don’t want to throw it out because someday you might have a reason to use (re-gift) it.

fruitcake

Yes, I did just compare your data to an old fruitcake

The above tips are not the end all be all, just things I have picked up along my career. But, if you are rolling into the discussion on data clean up just keeping these in mind you will be at a point where you have the business engaged in the ongoing process of data cleansing on a known set of data that involve a set of agreed upon classifications…or, in other words, you will be setup for success!

Oh, and now that this stuff is out of the way, we can get back to more techie stuff next week!

 

Andrew

Add followers with Flows

Standard

Chatter (in my opinion) is one of the really neat features of salesforce, allowing users to follow records that might be important to them is just one of the “Killer Apps” of this functionality. Ironically enough, being that this is a social network, is the request for that one can just add followers automagically if  “X” condition is met. There are even a couple apps on the appexchange for that.

Automated Networking, Jumbo Shrimp, Stop / Keep Moving, OxyMoron

Automated Networking, Jumbo Shrimp, Stop / Keep Moving, OxyMoron

To me, this takes a bit of the social out of “social networking”, so I am going to sketch out a solution that is a bit more personable but still makes it easy to add a follower

In a nutshell, it goes a little something like this:

1)      Within a record, the current user feels that another user (or themselves) should be on the follow list

2)      The current user clicks a button. In this case, I have called it “Pied Piper”

3)      A flow is launched that does the following:

1. Looks up a user based information given

2.Attaches that user to the current record as a follower

As usual, I am just sketching going to provide the foundation for this functionality. The magic here is that you can flows to do some neat stuff like attaching multiple users, adding comments, tags, etc. You don’t have to add this stuff in, but I would encourage playing around with it to see what you can / can’t do. Also, a quick Caveat. I found that a user will have to have “Modify All” permissions on the object you are pushing this out to. 

That aside, now we get to the Nuts & Bolts of the matter. I have got a couple of components that I am going to be using:

  1. A visual flow
  2. A custom button driven by a URL
  3. A nice cup of Coffee (Optional, or not)

This flow function sounds exciting and awesome (Follower Updates, Magic!), but is really basic. There are four components to this flow, Entry screen, Record lookup, Record Create and the confirmation screen (optional). There is however a critical variable, varAccountID. This is the variable that houses the ID that is passed over via URL. Just be aware when you are building this out!

The Components

Salesforce Flows, How awesome

On the entry screen, there is a text box for entry of a person’s name. The text box value is passed to the Record Lookup. One of the easiest improvements would be making this multi search (name, ID, email), just something to keep in mind.

Search Box

The flow does a look up on name, and returns the userID.

2014-05-13 13_15_27-Flow Designer_ public_FlowFromFlow

 

 

Next up is the Record Create on the object Entity Subscription. In this case, the parentID is the accountID, but it can be anything. SubscriberID is just the UserId pulled above.

2014-05-13 12_49_55-Flow Designer_ public_FlowFromFlow

Once the record is created, there is a confirmation screen. This is an optional step, but something I like to do.

Confirmation

Now that I have a flow in place, I create a button (Pied Piper) on the account layout.

Pied Piper Button

1 story point was spent on the clever name

This button is nothing fancy, just running a hyperlink that will open up the flow AND push over the accountID of the record the user is currently in. I did add the retURL on the end so that instead of a loop, the user is returned to the accounts page.

Behind the Curtain

Just to reiterate, this is the foundational work. You could implement this into production and have something that works but it isn’t going to be awesome. Here are the required proof shots!

 

As always, questions or comments, hit me up!

 

andrew

Delegation Made Awesome (Salesforce1Selfie Number2)

Standard

With my first salesforce1 selfie I took on user setup and reduced my “Click Load” when it comes to setting up users.

For this salesforcesforce1selfie, I am taking a swipe at the delegate process.

The org I support has quite a few approval processes and within these processes are a mix of related user (manager, for example) and named user approvals. Supporting these processes can be quite a challenge, especially around summer time since we are not using the delegate functionality. We have tried to roll out delegates, but never quite get off the ground with adoption. After taking a close look at the delegate function, reviewing notes from our last attempt and talking to the SFDC_IT team member I believe the lack of adoption is due to:

1)      No obvious click path to delegated approver screen (Click on Name, Click on Drop Down, Select “My Setttings”, Click on “Approver Settings”, enter delegate )

2)      Unable to start / stop time delegates

3)     Can’t turn on via mobile

4)     Too much mail if the Delegate is left “on” (See #2)

I believe that if I can add functionality that will help with the above, I can increase adoption of delegates. At the very least, like my clone user app, I can use it myself during the summer holiday season!

Hold on tight, here we go!

images

We got a long way to go and a short time to get there!

First things first, I needed to create an input method for my users that could be both easy to use and upfront. Therefore, I built out a custom object / tab combination, which I named “Out of Office”.

Out of Office

Can’t miss that!

I have as few entry fields as possible, both to speed the time to release but to also make it as easy as possible for the user:

1)      Start Time – Defaulted to current date

2)      End Time – User selectable date fieldThree Fields, one defaults

3)      Delegated Approver – Lookup field to user table

*Now, you might be reading this and shouting / typing furiously/ muttering about missed opportunities. I agree with you, and I feel certain that future revisions will get new / better functionality (Filtered Lookups, Approvals, On behalf of…etc), but this is about a good foundation to build on.

A quick look at workflows and I can see that I will have to do this with a combination of workflows and flows since I cannot update the Delegated Approver field with workflows, and

Narf

You know what I am talking about

In the interest of time, I am going to give an outline of the methods used to get this functionality up and running rather than the step by step.

Step 1, FUNctions used to update the delegate:

Workflow “OOTO Created” is triggered up on record creation. This workflow has two immediate actions, an email alert to both the delegate and the record owner and a flow trigger that runs a flow in the background that handles the actual update to the delegate. The flow really is basic, just a record update. I threw in a lookup out of habit.

2014-04-29 07_56_00-Presentation1.pptx - PowerPoint

The workflow also has a timed based action, which is the secret sauce. This time based action is based on “return date” – 0 and ticks the box “Back in Office”. Do not overlook the re-evaluate workflow rules after field change check box!

2014-04-30 08_30_30-Field Update_ Mark as returned ~ salesforce.com - Unlimited Edition

Step 2, FUNctions used to remove the delegate

Workflow “Remove Delegate” is ran when the field “Back in Office” is set to TRUE. This worklow has two elements (as I wrote it), but could get away with one. The main element is the flow trigger. This trigger launches another basic trigger that just deletes out the delegate from the record owner. The only thing special I did on this was to put in an extra field update in the flow so I can tell if it ran. I have a similar field update in my workflow. I found these to be very helpful when testing because I could visually observe how my updates were working.

2014-04-30 08_42_16-Workflow Rule_ Remove Delegate ~ salesforce.com - Unlimited Edition

Move along, nothing to see here

Now, for the brass tacks, how does it work? Well, it works pretty dang good. I have been monkeying around with this for a couple weeks now and I can attest to the basic functionality. The only real weak link in the process is that I cannot directly influence the field “Receive Approval Request Emails” setting via the flows. That, however, can be handled with business process.

2014-04-30 08_45_27-User Edit_ Andy Johnson ~ salesforce.com - Unlimited Edition

Curse You!

Now, for the 10,000 dollar question. How does it look on Mobile? Well my friends, it looks pretty darn good. Salesforce1 does such a nice job of packaging up the objects created that you get a very nice experience out of the box. This is such a nice contrast to previous mobile versions. I can focus now on making the user experience that much better.

2014-04-29 07_56_56-Presentation1.pptx - PowerPoint

Yeah, that is awesome

For example, I built out a field that shows a message based on a couple parameters: “if(Back_in_Office__c =FALSE,”Out of Office, returning “& text(Return_Date__c) ,”In Office”)”

I added this field to a new compact layout, and viola, the user can now, at a glance, see if they are in office or out of office, and if they are out of office, when they are coming back (NEVER!)

In OFfice

Awwww

Out of Office

Woo Hoo!

 

So there you have it, another piece of adminsitrivia solved with Salesforce, Visual Flows, and Salesforce1

 

Andrew