Wow! Thank You!

Last Thursday I was met with some very good news. I am now a Salesforce MVP, class of Spring ’15!

I think its all still settling in but wanted to take a moment to thank everyone who nominated me. I’d like to thank the current MVPs who were part of the process as well, if it weren’t for the encouragement of my MVP mentor Vamsi Krishna, and other MVPs who were there as a sounding board for me (Bill Greenhaw, Sarah Deutsch, Brian Kwong to name a few) I’m sure I’d not have had the chance to have this experience.

Its very humbling. I interact with a number of superstars in this community who are certainly MVP material and here I am — one of them. There truly are not words to fit the occasion. (Actually, there *are* some words, but I’m still putting them together).

Now I must ask you all for a favor: If there’s something I can do to help give back, something you’d like to see me try (e.g. put together a blog post about a specific topic, maybe even speak on a certain topic perhaps — which scares the bajeeezus outta me), anything I can do, please let me know. Hit me up on twitter, even facebook, email, here in the comments, smoke signals, whatever — I’m here. I don’t like to make it obvious, even downplay it a bit at times, but I LOVE interacting with the community, so don’t be shy :)

Again 1000 times thank you!!

 

:wq!

 

Find Your Mantra

Recently I was asked a question to describe what exemplified me as a coder, preferably with an example of code. It was odd, not something I’ve ever really thought about. I write code and attempt to leverage the pluses of a given framework and work around the minuses. I don’t have one “goto algorithm” for sorting things, or a given methodology that could be described in words let alone code, so I got to thinking, and thinking, and thinking. All I came up with was one simple rule: “Write easily digested code.”

I’ll be straight, I’m 40 years old, been in IT for over 20 years, and I’ve not the time nor desire for flexing my coding muscles by showing of my implementation of  the “modified pre-order tree traversal” algorithm. I’m not gunning for a job at Google, or looking to be a star on Top Coder, etc. I’m here to “get shit done” in a sensible, maintainable, and easy to understand way. Perhaps its my python background that taught me that there is elegance in simplicity and much value to be had in explicit versus implicit code. Sometimes that may seem like the long way around but in the end, even the most “showy” of developers wind up appreciating something simple. We stare at problems all day, one of those problems need not be deciphering someone else’s “mental inspirations” in their code.

MOST of us aren’t coding to save lives, put someone on the moon, or write high performance platform games. MOST of us don’t have to worry about the “Big O” of a given algorithm. I save that for the people *way* smarter than I am. I rarely have to dust that sort of skill set off and when I do, you can be darn sure I will have no less than 22 tabs open in Google walking me through it.

At the end of the day, when I move on in this world, whether figuratively or otherwise, I want whomever inherits my code to not have to sit back and scratch their head, or re-read a section of code over and over to make heads or tails of it.

I’ve talked about writing clean code before, but this goes even beyond that a little bit. Its really one of those things that are hard to talk about until you’ve seen it. I’m always striving to make my code simple to comprehend, but not just by seasoned programmers but by the young intern that’s gonna be inheriting your code someday.

I’m not exactly sure the person I was talking to was pleased with my answer, it was probably nowhere near academic enough to hold their interest and probably seemed like a cop-out. It may be a cop-out to them but for me, its sort of turned into a mantra: “Write simple and easily ‘ingestable’ code”

 

:wq!

Just For Fun

Time wasting links edition:

Nothing techie today folks. Sometimes we need a “checkout,” time to take a step back, take a breath and reset. Sometimes our minds get so clouded we forget to have fun. So lets have some fun shall we?

Since music is my release my first sidestep is this: there’s another Salesforce singer in our midst: Shane McLaughlin (@MShaneMc) so welcome to the show Shane. :) (admittedly I’m slightly jealous of his 330 views!! “Ima let you finish but….”

Continuing with music, for karaoke lovers: did you know you can sing karaoke online? Well you can: and I did. If only I had more time to waste! (It even lets you do duets with  a stranger #harmony!!).

Then there’s this magnetic putty stuff: #creepy — reminds me of the blob but yet I still wanna score some. Not exactly what I’d do with it aside from creep my children out, maybe there’s some fun Halloween type thing I could do with it…

And Office Space has come full circle. How very meta. Whatever happened to Michael Bolton anyway? Either of them?

Oh, sorry back to music for a moment: I KNOW this guy!! He’s awesome. And I seriously don’t know whats wrong with Pharrell & Christine, “Is this thing on? Hello? Testing 1,2,3!!” Oh and go checkout his old band (and I went to high school with his bandmates Andy & Joe Wilson).

Anyway — alas I must work.  Projects to start, code to write, and sunshine in my window to enjoy (at last!)

:wq!

 

 

 

 

 

 

Have You Nominated Your Hero Yet?

It’s that time of year again. No, not the time to spend money on cheesy I love you cards, and calorie filled fake chocolates…I mean its time to nominate your Salesforce Community Heroes for MVP status! I’ve cast my vote(s) for some very deserving folks. Nomination is very important. Its well within your control to see the community become what you want/need it to become by selecting those you want to see help drive the passion behind the community! So what are you waiting for…just do it!

Having trouble choosing? Not sure what makes a good MVP? I’ve talked about here before.

 

:wq!

When an Email Template Just Isn’t Enough

Sometimes your users need to send an email from within Salesforce. Most of the time the standard Send Email button will suffice. Other times however, your needs are more specific. For those times, developers often resort to using Visualforce email templates which can certainly meet just about any need. However, the drawback here is that the email content now lives in code. Being good developers, we don’t want our admins to have to worry about digging into code for things like this — unless they really want to — so we try to come up with a way to make the content of the email accessible. This was my exact requirement and here’s what I wound up doing. The code herein is very specific to the requirement in question but could be generalized a bit to make it more flexible or reusable (which is something I may just do at some point, but alas — deadlines. @Codefriar has already done some pretty cool stuff here.).

Here was my approach:

The Template:

I created a new Email Template just as one would for use in workflow email alerts etc. I then created a custom settings to store the ID of this email template in this particular application’s custom settings. I will use this ID later to get the ID of this template in my apex class.  In the content of this email I included the merge field syntax (more or less because it was familiar to people) for the fields that I knew I was going to be including later.  In the end I wound up with a template that looked something like this (any client identifiable content has been replaced with BLAH BLAH BLAH — I’m so creative…):

Dear {!Contact.Salutation} {!Contact.LastName},
I am pleased to attach the final BLAH BLAH BLAH document between {!Opportunity.Account} and the BLAH BLAH BLAH for your records.

BLAH BLAH BLAH is proud to work with {!businessTypePlural} such as yours to fulfill new opportunities in BLAH BLAH BLAH.

Thank you for your commitment to your employees, your community and the state of BLAH BLAH BLAH.

BLAH BLAH BLAH is always looking to improve our services. Please take the time to fill out a brief satisfaction survey using this link:

{!surveyLink}

Sincerely,
Some Person at BLAH BLAH BLAH

Some of those items I could have set using the standard setTargetObjectId, setWhatId methods available on Messaging.SingleEmailMessage, but those wouldn’t get me to some of the other data that I needed. So instead, I used the template merely for its body content and manually performed string replacements in my apex class on that body like so:

public EmailTemplate emailTemplate {
        get {
            if(emailTemplate == null) {
                Survey_Settings__c settings = Survey_Settings__c.getInstance();
                if(settings != null) {
                    emailTemplate = [SELECT Id
                                     , Subject
                                     , Body
                                     , HtmlValue 
                                     FROM EmailTemplate 
                                     WHERE ID = :settings.Contract_Email_Template_ID__c];     
                }
            }

            //send in the Contact for salutation purposes
            if(this.selectedContact != null) {
                Contact c = this.oppContacts.get(selectedContact);
                if(c != null) {
                    if(c.Salutation != null) {
                        emailTemplate.Body = emailTemplate.Body.replace('{!Contact.Salutation}', c.Salutation);    
                    } else if(c.FirstName != null) {
                        emailTemplate.Body = emailTemplate.Body.replace('{!Contact.Salutation}', c.FirstName);    
                    }
                    
                    emailTemplate.Body = emailTemplate.Body.replace('{!Contact.LastName}', c.LastName);
                }
            }

            emailTemplate.Body = emailTemplate.Body.replace('{!Opportunity.Account}', this.opp.Account.Name);
            emailTemplate.Body = emailTemplate.Body.replace('{!businessTypePlural}', this.opp.Account.Business_Type_Plural__c);
            
            return emailTemplate;    
        }
        set;
        
    }

Much of the above, (if not all) could have been achieved by just sending in my contact. I could have gotten most of the necessary information from there, however — in so doing, the body of the email would have been rendered but I still don’t have all of my information, particularly my survey link. I wouldn’t have my survey ID yet either as that doesn’t get created until my end user clicks send. By then it would be too late for me to stick the survey link since the email message would be already packaged up. (I did try this, before going this route but ran into some odd issues getting my link in the email message, so I backed out and moved forward with this plan). Add to that the fact that I wanted to show the content of the email WITH the substitutions in place to the end user for review.

Lastly, once the user has selected their attachment and has proofread, perhaps even modified the message (minus the link since it doesn’t exist  yet) they click send. I then save all the necessary objects, including my survey and stuff that into the email message before calling my sendEmail method.

private Messaging.SendEmailResult[] sendEmail() {
        Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
        List attachments = new List();
        Messaging.EmailFileAttachment contractFile = new Messaging.EmailFileAttachment();
        contractFile.setFileName(emailFile.name);
        contractFile.setBody(emailFile.body);
        attachments.add(contractFile);
        msg.setFileAttachments(attachments);
        msg.setSubject(emailTemplate.Subject);
        msg.setToAddresses(new String[] { this.oppContacts.get(selectedContact).Email});
        msg.setHtmlBody(emailTemplate.Body);
        Messaging.SendEmailResult[] result = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {msg});
        return result;
    }

Which gets called from this hunk of code in my save method on the controller.

Survey_Settings__c settings = Survey_Settings__c.getInstance();
                if(settings != null && settings.Customer_Satisfaction_Survey_URL__c != null) {
                    String surveyUrl = settings.Customer_Satisfaction_Survey_URL__c + '?aid=' + this.survey.ID;
                    emailTemplate.Body = emailTemplate.Body.replace('{!surveyLink}', surveyUrl);    
                }   

                //send the email
                emailTemplate.Body = emailTemplate.Body.replace('\n', '
');
                Messaging.SendEmailResult[] result = sendEmail();

I then manually create an activity that logs this message and includes the body of the email in the description field of the task. The task is set to Completed in code so it goes directly to Activity History.

In the end, the solution provides full access to content to the admin, and full control over the flow complete with some extra automation that they couldn’t get out of their old process.

Hope this helps should ever find yourself in a similar situation…

 

:wq!

Getting Back to Basics

Sometimes we get so good at what we do or we do what we do so often, we wind up flying on auto-pilot. Whether this is evident in your personal life, or work life — its pretty much unavoidable. Given the nature of this blog however, I’m focusing on work life. Being a consultant, I get to poke around at numerous orgs. Most of these orgs have been around for longer than I have and may have perhaps lost their admin, never had an admin, or have just been “brought along for the ride” and when I show up there are many basic things I see that could possibly help the organization in question maintain a better environment for their data, especially when inviting “outsiders” into their org for support.

Here are some items for those entities that don’t have a dedicated salesforce admin to keep in mind when working in their org that go a very long way to producing an environment that is easily support or passed on from one admin to the next, etc.

  1. Fill out description fields, for everything. When adding a new field to a standard or custom object (or even just adding a new object, etc), you are given the option to fill out a description field. Use this. As far as what to say — think about what you would want to know about this field if you had no prior knowledge of your org.  Be explicit, and avoid company specific abbreviations etc. (As an outsider looking in for the first time, you’re likely not going to know all the internal vernacular used within a company, e.g TPS Reports). This has the added advantage of reminding yourself what a certain field is there and what it does should you not need to work with part of your org for sometime. If you’re at all like me, if its been off your plate for more than a week or so — you’ve forgotten it. The description field is a great reminder.
  2. Naming standards for fields: If you can, be explicit in your naming of fields.  A field name ip_Total__c might not be as clear as Internal_Product_Total__c. For a little more typing, you’re building documentation directly into your objects. Yes you can be more explicit in your labels, but speaking purely from a developer point of view, if I’m using Internal_Product_Total__c in my code instead of ip_Total__c, my code just got easier to read as well. (So thanks in advance for that!)
  3. Naming standards for everything: Okay so this may be a cheat just to add another number to this list, but lets forget that for a moment. Why not be as explicit as you can with the naming of things like workflow rules, workflow actions, email templates, email alerts. If it can be read/referenced why not make it clean and obvious what its doing or what its being used for? “Send Email” is nowhere near as clear as “Send Internal Products Total Goal Reached”, etc
  4. Eliminate cruft: This one is a bit tricky as I’m never a fan of deleting…anything, but I’ve poked around enough orgs that I’ve seen many an attempt at writing a validation or workflow rule only to abandon it later for one reason or another. If its in your org and never been used, or something you were just experimenting with — get rid of it. That’s what sandboxes and dev orgs are for. Which is a great segue…
  5. Don’t make changes in production: this is dangerous. Even if it seems harmless you can do bad things. Bad things, in case you were confused, are not good things (unless you learn from them, but again…you can learn from a sandbox or dev org as well). Playing the “what if” game in production is scary for your data…your data doesn’t like “what if” — it likes routine…and tidiness, and maybe long walks on the beach…data is king, honor your king…its good to be king.

To most of you reading this this is hopefully review, however since I only make the effort half the time myself, this is as much for me as it is the newbie who might be wandering out in the big world of Salesforce for the first time. (Do as I say, not as I do right?).

P.S. I promise I am working on some more technical “stuff” but I’m still fighting my way through some of what it is I want to show, but its coming…I swear…I have here somewhere…kinda.

 

:wq!

Handling Objections

Often times developers get set in their ways. We like our “norm” and don’t like to change things up all that often. Don’t get me wrong, many of us — perhaps most of us spend time with the “framework of the month” but usually wind up falling back into our platform of choice. I remember when I was fed up with all the various frameworks within the Java world and someone showed me CodeIgniter for PHP. I jumped ship as soon as I could and for the longest time nobody could sell me on anything else. I’d tried rails, and grails, and while those were “fun and new” I was just not as productive or enamored with what they supplied me. From there, someone showed me Django and though it took quite a while for me to gain an appreciation for it, I eventually crossed over. The frameworks were all similar enough in concept to keep me learning at a good pace and eventually it became my framework of choice.

Recently I was a “fly on the wall” during a conversation regarding the introduction of the Salesforce platform to a team of largely Java/Grails developers & while the voice in the room was playing devil’s advocate, he was simply spot on regarding some of the objections that his developers were going to throw at him. As I sat and listened intently (as I’ve been down that road before) I started to think of how I may respond to some of the objections.

  1. I don’t want to be locked into a frameworks way of doing things: lets be honest, there is not a single person on the planet that is part of a Java project that isn’t currently submitting to some framework’s way of doing things. You’re likely using Spring, JSF, Hibernate, etc. You’re doing things the frameworks way already, you’re actual objection is:  “This is new and I’m not used to/don’t want to learn something new.” The beauty here is that if you’re comparing it to Java — the languages are extremely similar and the front end templating is definitely nothing new if your used to jsp tags, JSF, etc. There is no lock-in here that you aren’t already experiencing. When you use a framework you’re accepting its way of doing things. This is no different than what you’re already doing, its just a different “lock.”
  2. Licensing costs — we currently have none: While this is true if you’re not in the .Net world, you likely don’t have licensing costs but you have server upkeep costs. Whether you colocate, outsource entirely, or have your own server room, there is quite a bit of cost built into maintaining your installations, configuring your app servers, locking down the security, applying patches, etc. And lets not forget how much “fun” it is troubleshooting JBoss stacktraces, load balancing your database servers etc. If you’re a server guy, great — you lasted a heck of alot longer than I did, but if you’re DevOps (by force) wouldn’t it be nice to focus less on the Ops and more on the Dev?  While I’ve not run any numbers, I’d bet that once you figure in maintenance of your servers, the licensing isn’t as bad as you’d think. (Lets talk High Availablity, redundancy, failover, disaster recovery another time…*ouch*)
  3. I like to build my front ends from the ground up: So do many people, and many still do. I still haven’t fully submitted myself to Visualforce and often times layout pages with standard HTML. I use JS libraries, stylesheets, the same tools that straight up HTML5 guys are using. The Salesforce platform allows all of this — and guess what? I’ve still managed to learn a thing or two outside of the platform.
  4. We already have a system in place that works for us: That’s great news, but should that force your company into doing things the same way even if given evidence of perhaps a better way of doing things? Shouldn’t you at least want your company to attempt to improve? It may very well be that your way is better, but a company that doesn’t at least explore other avenues in a quest for improvement is doing itself — and its employees — a huge disservice.

In the end we developers are a finicky bunch. We like what we like and many times we can’t really tell you why, or when we do — our arguments seem purely emotional and not always logical. As a developer, I’m trying to keep an open mind about things, and I’d like to think I’m fairly good at that most of the time. After all, I left Django and decided to learn the Salesforce platform. Yea, sure there are things I really miss about Django, but if I went back to Django, I’d miss things from Salesforce. Its about learning, the experience in trying new things. If you’re argument is that you don’t want to be pigeonholed into another framework but then only offer up your “goto solution” — aren’t you already pigeonholed? #FoodForThought

 

:wq!

Hello 2015

2014 was a good year. I started flying solo on more projects, became more confident in my own abilities, had an awesome Dreamforce, and began to get a bit more comfortable in my own skin. Largely in part due to me finally saying to myself “screw it, just do what you’re gonna do and don’t worry about what others think of you” — I’d like to say that I’ve held on steadfast to that mantra, but like any new years resolution I had my moments :)

I released two original Salesforce related songs, one of which found quite a following due the the existence of a well established “ThatWhySFDCAdminsDrink” hashtag, the other — not so much. However, I did it. I put myself out there and just said “to hell with it” and I had fun doing so, and plan to do so again (so you may get sick of me).

Since we’re on the subject of what I hope to do this year, maybe this is the perfect time to talk about the traditional “New Year’s Resolutions” — these are probably more “goals” than anything else, but I’m stalling so:

Salesforce/Career:

Since I already have my developer cert, and since @KevinSwiggum wants me to get my admin cert, I suppose I should focus on getting that taken care of this year. It really was supposed to happen during my “employment year” so I technically still have until May and I’d like to meet that goal, but when you are part of a small company — priorities shift. I may not make May — but I want to have it done this year.

While we are speaking of certifications, if I indeed make the May timeframe, I’d like to move on to my advanced admin certification. It just seems like something I should do and its something I may not need, but I want. Its the first time ever I’ve actually *wanted* to get a certification.

I want to be more present in the Success Communities. Not just with the music that I hope to continue writing, but in answering questions and being more present and available overall. This will likely prove to be the most difficult for me as hanging out in the Success Communities during work hours is something I don’t want to make a habit of, and being a family man, doing so after hours isn’t ideal either. However, I think I can add value and will continue to figure out a way to do so.

Lastly, I want to find a way to get through the workday with less distraction. Often times I’m coding away and I’ll notice an incoming message or notification of some sort. These notifications are very rarely “important” for work so the less I give them notice during the day, the better. That may mean only checking my email at specific intervals during the day, turning off Twitter desktop notifications, etc. The really important things will fall through to my phone from those people that really need me.

Personal:

Get back to the gym. I was a three-day-a-week gym rat for a good part of the year, however since I was going over the lunch hour it began to feel as if I was taking too much time away from work. I’m not one of those people that can get up and work out a 5am — my body just doesn’t respond during that time. My mid-day workouts feel better. In April my contract with my current gym is up and I can switch to the gym that practically shares a parking lot with my employer. That will make the lunch hour workouts easier, so its just a matter of getting “something” done between now and then.

Try to write a new song a month. These won’t necessarily all be SFDC related, but I truly enjoy the process. However, I don’t expect this one to stick as I tend to run hot and cold with my creative streaks. I’m also very picky and if it takes me more than 30 minutes to get lyrics down on paper I usually toss the whole thing. Words should just flow and if I’m struggling to make things fit I feel like you can tell in the final result.

Try to play my trumpet on a weekly basis. The trumpet was my primary instrument for 14 years of my life and then apartment life began and I had no place to practice without making neighbors angry. I’ve since lost whatever it was I had back in school. Nowadays, when I hear a Maynard Ferguson tune, or any other trumpet player for that matter — I find I miss it. I’ve got quite a bit of work ahead of me for this but am looking forward to it.

Lastly, blog. I missed a couple weeks at the end of this year due mostly to workload, but hitting a deer with my truck and lack of content that I thought would be actually “something worth saying” were major factors.  I think coming off of Dreamforce with a high level of excitement like I did set me up with some high expectations for myself in this arena. It wasn’t much “work” for the first couple of weeks, but now I’m feeling the true “burden” of coming up with something worth writing. All I can do is try.

In closing, I know some of these things will slip but if I can at least find balance between work, home and my first love music then 2015 should be a good year.

What are some of your hopes for the coming year?

 

:wq!

 

Wednesday Wrap-Up November 2014 Edition

In keeping with my concept of copping out wrapping up the previous month’s events that I found interesting, or mentioned here on the blog, I copped out present to you the latest edition of the Wednesday Wrap-Up. *cough* cop out *cough*

Personal Happenings:

  • I released a Salesforce Christmas song titled “Christmas in the Cloud” — Consumption has been really low though. Hey they can’t all be awesome its not like I’m Taylor Swift or something! (note to self: never release on the day before a holiday during a short work week…#duh)
  • Thanksgiving happened, we hosted — ate too much, then had Thanksgiving Part Deux at another relative’s house where nobody quite understands what it is I do exactly.  “I do computers” thanks @Michaelforce
  • I was given way too much credit for helping Sarah Deutsch write this parody. #Awesomeness — I maybe added three or four lines, but it was a blast to be involved even that much.

Industry Happenings (that I actually cared about):

Okay, confession time: I was very disconnected this month from anything that wasn’t project related. I’ve been living in a self-absorbed worldly mix of jQuery, Visualforce and Apex for several of my clients. Apple could have released the next big thing and I’d have missed it. Throw in the holiday on top of that and for all I know, we’ve invented teleportation, space elevators, and consumer-grade flying cars. To be honest, anything that did catch my eye I forgot to bookmark, except for this: (hint, someone hooked up their car to Salesforce).

So to make it up to all four of my readers — I have some Ello invites hanging around here somewhere, if you want one, let me know.

 

:wq!

Christmas in the Cloud

The official start of the holiday season is upon us. I tend to be a bit of a Grinch until closer to Christmas, so I decided to write a holiday song to help me pull out of it early this year. However, the subject took a turn towards Grinchy as the hero of our story gets stuck working on Christmas Eve.

I present for your — (hopefully) — enjoyment: Christmas in the Cloud