Clone User – Lightning Awesome

Standard

Way back in the old tyme days of 2014, Salesforce was running a contest called #Salesforce1selfie. I decided to try porting my clone user flow (Spoiler, totally worked) but that isn’t the fun part. The fun part was using flows for MY gain!

marsha marsha marsha

Andrew, Andrew Andrew

But, that was 2014 and it is now 2017 and Lightning is now the cool kid on the block. So, going to take a revisit to the old clone the user app and see about making it more 2017 than 2014.

First things first, I had to recreate the clone user flow. Surprisingly enough, you really just need to follow my previous mentioned post and you are good to go. You gotta make sure to activate it though.

The real change is on the page layout. The easiest way to to do this is to go to a user record, click on the gear icon and then click on edit page. Sorry for the crappy screenshot, new computer.

user click on gear.PNG

Now that you are on the page edit layout (I am sure there is a better technical name!), I would do the following, though the ONLY required part is adding a flow widget.

  1. Add in a tab widget.
    tabs
  2. Reorder the tab widget so that related is on the right.
    swap done
  3. Rename details tab to your variation of clone user.
    renamed section
  4. Drag a flow widget to that tab.
    flow widget
  5. Set the flow to be your clone user flow and the variable to be the record id.
    pass variable

Go ahead and save the changes and make sure it is set to be the default of whatever you have setup. Click into a user profile and behold, the tab that says Clone User!

user page

Click on that tab and WOOT, the user ID from the source is passed.

clone user on page.PNG

The rest is literal history. You don’t even need to really update the original flow!

Questions, comments – Let me know!

 

andrew

Advertisement

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

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

 

 

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

2 cents on Salesforce Process Builder

Standard
Quarter

OK, maybe .25 cents worth!

I started playing around with Salesforce Process builder and I figured I would give the world my 2 cents on this new functionality!

The process builder is a HUGE step forward. It is really cool, especially considering this functionality is less than a year old. If you were amazed by what you can do with #ClicksNotCode before, this will be mind blowing.

3 things I like:

  • Up to 5 decision points. Raise your hands if you have ever had to dissect a HUGE workflow with multiple gnarly logic steps…OK, this one is for you all. Stop weeping, process builder is going to help tremendously. What I like is that you can have up to 5 conditions grouped under a process that run really as separate statements.
  • Run LOADS of Actions. There is NOTHING quite a fun has building out a super awesome workflow and then rebuilding the logic so you can run an approval process #sarcasm. One place for all this stuff now!

Only one not present Make me coffee

  • Great UI. I love Visio. Seriously, love it. The UI of process builder makes documentation a snap since you can just grab a screen shot and see in pictures what the heck is going on. You know what would make this better though? A Nice “Click here to Print” button that would print out the process along with all the “stuff” with it. Yes, I used “stuff” as a technical term.

3 things I don’t like:

  • Versions are a PAIN. To be fair, this is a beef I have with Flows as well. I should be able to deactivate, make changes and then reactivate. One of the MAGIC things with workflows is that you could make a change, save it, test it and be done. With Process Builder, you have to clone, enter a new name (WHY!), save then activate. If you find something goofy, guess what, same dang process. Much like flows, you very quickly generate a TON of versions.
pain

Speak it Grumpy Cat!

  • Can’t edit an inactive version. Yep, this is another versioning thing. One of the things I particularly like about flows is that I can step into a previous version, make edits and save it. Of course, there is a warning that I cannot over write the previous version, I have to save it as a new flow or new version of the flow. Sometimes, if your versions are different enough, you have to dig in and see what you could have done differently.
  • Replacing Precision Tools. You could create a flow trigger stupid fast. You could do it from multiple screens and you could edit it after you have associated it with a workflow. Here is a corny analogy. Let’s say that you noticed you have a screw loose on a piece of furniture. To tighten the screw, you would go and grab the cool screw driver with multiple bits out of your tool box and tighten the screw. This is like using a flow trigger. Just the minimum to get the job done! If you were to do this same action the process builder way, you would grab the WHOLE toolbox which includes tape measures, hammers, pliers, pencils etc…and bring it back to the furniture. Sure, the toolbox contains the screw driver and you are accomplishing the goal, but you just don’t have to lug that toolbox around.

So, that is that. Let me reiterate again…I love process builder and I think it is a  fantastic piece of tech, but don’t take away the precision tools because the tool box is getting fancier!

Reducing the amount of email while sending email

Standard

In my post titled “Cleaning the data that matters – and not all data matters” I finished the post up with the following:

“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!”

To which, JaneIsaac replied:

“nice detective work. Could you share What the timer formula look like?”

Well JaneIsaac, this post if for you!

Not that type of request

I take requests…just not freebird!

The scenariois that we wanted to send out alerts if an account scored low data grade points and that account OR an opportunity related to that account was updated. After some quick research I saw that the updates were clustered, often receiving multiple updates in a short period of time. I didn’t want the alerts constantly kicking out.

So I built out a function so that prevent multiple alerts from being sent out in a given set of time. My functionality treats account and opportunity updates as two different actions, so I broke them out on this blog as such. Listing out the ingredients below and I will dissect the basic functionality after.

Must be about snack time...

Ingredients for tasty food, not tasty Workflows

For the Account alerts:

1 – Date field on Account “Data Alert Sent Date”

1 – Workflow rule for the Account Object “Data Grade Alert”:

Evaluation Criteria = “Evaluate the rule when a record is created, and any time it’s edited to subsequently meet criteria”

Rule Criteria =

Account WorkFlow Criteria

AND(
AND(Account_Data_Grade__c <>”Acceptable”,Account_Data_Grade__c <>”Excellent”),
Open_Pipeline__c < 1,
AND(LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “,LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “,LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “, LastModifiedBy.ProfileId <>”xxxxxxxxxxxxxxx”),
(DATEVALUE(CreatedDate)<>Today()),
OR(ISBLANK(Data_Alert_Sent_Date__c),(Data_Alert_Sent_Date__c) <> today()))

2 – Immediate Workflow Actions

All about that (Account Workflow) action Boss

1 – Workflow email alert Sendemail to “Last Modified By”

Account Workflow Alert

       1 – Field Update “Data Alert Sent Date” with Today()

Account Field Update

 For the Opportunity alerts:

1 – Date field on Opportunity “Data Alert Sent Date”

1 – Workflow rule for the Opportunity Object “Data Grade Alert”:

Evaluation Criteria = “Evaluate the rule when a record is created, and any time it’s edited to subsequently meet criteria”

Rule Criteria =

Opportunity Workflow Criteria

AND(
AND(Account.Account_Data_Grade__c <>”Acceptable”,Account.Account_Data_Grade__c <>”Excellent”),
AND(LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “,LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “,LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “, LastModifiedBy.ProfileId <>” xxxxxxxxxxxxxxx “),
Record_Type__c =”Open Opportunity”,
(DATEVALUE( Account.CreatedDate )<>Today()),
or(ISBLANK( Data_Alert_Sent_Date__c ), (Data_Alert_Sent_Date__c)<>TODAY()))

2 – Immediate Workflow Actions

All about that (Opportunity Workflow) action Boss

1 – Workflow email alert Send email to “Last Modified By”

Opportunity Email Alert

          1 – Field Update = “Data Alert Sent Date” with Today()

Opportunity Field Update

Taking a look at the mechanics:

I wish my cube was this cool...or that I had a flying monkey!

I wish my cube was this cool…or that I had a flying monkey!

The rule criteria’s are similar enough that we won’t have to dissect them both and since the interest is in the timer components, that is what I am going to focus on:

1)      (DATEVALUE( Account.CreatedDate )<>Today()) –  Ignore if the account is newly created

2)      But, the following situations are OK:

  1. (ISBLANK( Data_Alert_Sent_Date__c ) – The data alert sent date is Null (Never triggered before)
  2. (Data_Alert_Sent_Date__c)<>TODAY() – The data alert sent date does not equal Today()

This last line is what ensures that an alert will only send once per day. If the rule runs, (Data Quality = Poor and “Data Alert Sent Date” <>Today()), then the email alert gets sent out and the “Data Alert Sent Date” gets updated with the current day. If that record was updated ANY OTHER TIME during that day, the rule will not fire. I know I say this all the time, but what I really (Really) like about salesforce is that when it comes down to it, you can do some crazy cool stuff with zero code.

Clicks Not Code!

In other CRM’s, the above functionality takes 6 weeks and 2 developers.

 

Looking at this functionality now, I think a couple neat additions would have been:

1)      A rollup summary on opportunity.Data_Alert_Sent_Date__c (MAX), this way, you could have the account rule also looking at the last time an alert was sent out on ANY opportunity.

2)      A counter field update on the opportunity rule with a corresponding rollup on accounts. This would allow for reporting on ignored updates and thresh holding of the alerts.

But, the fun with Salesforce is the ability to rapidly prototype and tinker, so if I wanted to add in some new stuff, it is easy – peasy – lemon squeezy.

Well, hope you enjoyed this. I certainly had fun taking a look at something that was built out quite some time ago but continues to keep ticking! If there are any special requests, just let me know!