I recently was working on a project where we needed to override the new and edit pages for Accounts so that we could do some custom duplicate checking before the user saved the record. In standard override fashion, I created a Visualforce page with a controller which looked something like (edited for brevity):
I first tested it in the full site to make sure it would work there:
So far, everything works as expected.
Next, I tested it in Salesforce1 to make sure it would also work there (this particular client is a heavy user of Salesforce1).
As you can see, although the birthdate saved successfully the billing address did not. Doing some digging, I was able to see that the address was indeed correct in the database, so just pulling down on the screen to refresh the record, I saw:
Now the Billing Address is correct. It looks like the problem isn’t with the saving, it’s with the form refreshing correctly.
At this point, I opened a case with Salesforce support. After some back and forth, they eventually escalated it to R&D where a bug was submitted: https://success.salesforce.com/issues_view?id=a1p30000000T5awAAC. If you are affected by this issue, please click the button – it will help prioritize this bug fix above others.
Are you seeing something strange in your organization? Need some help figuring out what’s going wrong? Contact us and we can help.
The Winter ’15 release window is upon us, and with it another round of exciting upgrades and updates geared at making our lives easier and the software we rely upon more stable. As always, Salesforce is delivering a sizeable number of updates to the platform, which generates quite a large release notes document. To save you the time of having to read the entire thing, we’ve handpicked our top updates that we think are most important based on the amount of impact we think they will have on us and our clients’ lives.
While reading this, you may notice this post is lighter on graphics than normal and this is intentional – Salesforce has done a great job of providing screenshots and examples in their documentation as appropriate, so we encourage you to go read the official documentation for any feature that interests you.
This beta feature uses Data.com to help prevent duplicates from being inserted into the system. The rules for detecting duplicates and choosing whether to allow them are customizable and reportable, so you still have full control over your data.
This is a big deal to us. Arguably the single most requested enhancement we do on the platform is duplicate detection and prevention, with nearly every client having this in some form or another. Using this feature, some of the work is done for us. Although it does appear to require Data.com licenses, this is still a valuable addition for our clients who already license Data.com, and may make the added cost now worth it for anyone on the fence.
This feature allows you to view data in an external system as though it were data in Salesforce. You can add this external data as related lists to normal Salesforce objects, form relationships to it and treat it almost like it actually lived in the platform itself.
This has a lot of potential to redefine how we approach some integrations. A common reason for integrating in the first place is to allow the user to view all appropriate data in one place. Generally, these integrations are not real time, so the user could potentially be viewing stale data when making decisions. This feature would be querying the other data source directly, reducing the effects of stale data.
This feature does require an OData endpoint to work, however, so custom code may still need to be written if the external data source does not support OData natively.
This feature allows users to now convert leads to Contacts and Opportunities from within Salesforce1.
While this feature seems small, it is something we are glad to see Salesforce has added. It is something we have had clients ask us for in the past, and lead conversion is surprisingly complex so it’s nice to have it already handled for us.
This feature exposes a new global variable for use in formula fields, validation rules, and Visualforce pages. It makes checking the user’s permissions easier and moves it out of the realm of custom code.
Another relatively small feature that can have large implications. Before this feature, we had to write trigger or controller code to check the user’s permissions if we wanted to do this kind of logic. With this feature, we can now put those checks in validation rules or formulas, reducing the amount of code we need to write, saving the client money and reducing the delivery time.
This feature allows us to deploy updates to environments that may have scheduled/running Apex jobs without having to first cancel those jobs, making deployments quicker and less painful than before.
Our My thoughts
Ok, I admit that I may be the only person here who is excited about this feature (not many people get excited about deployments) but it is a good one (and since I write the post, I’m including it). I’m excited that I can deploy updates to (usually scheduled batch) jobs without having to cancel and reschedule them. While this does come with some amount of risk (the job failing if it’s currently running) I think the reward outweighs the risk in most cases. As always, it is important to understand the details of what you are doing to minimize unexpected outcomes.
This feature changes enhances how asynchronous jobs are written and executed on the platform. It adds additional flexibility for queuing up multiple jobs.
This is a very developer-centric update, but it is one that has deep implications in some of our designs. A common scenario we face during integrations is needing to make callouts to external systems, which can only happen asynchronously. This enhancement provides us with a new, very flexible way of approaching these requirements and the chaining helps us navigate around some of the governor limits that have been painful in the past.
Obviously, with a release this large there are far more changes than what we covered here, so we encourage you to go read the release notes if you are looking for something specific. If you have any questions or are curious about anything in the release notes, feel free to contact us and we will do our best to assist.
Today's guest blogger is Ian Moore, a Developer at Sonoma Partners.
To accomplish this, we will need the core Angular module and the ngResource module – which helps your code interact with RESTful APIs like the OData endpoint. You can download the two modules yourself from code.angularjs.org, or you can include them from a CDN like so:
<script src="https:// ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.19/angular.min.js"></script>
<script src="https:// ajax.googleapis.com/ajax/libs/angularjs/angular-resource.min.js"></script>
Now let’s create a new Angular module for code we would like to share between projects. We can call the module “angularMscrm” and, using the .factory() method, define a new Angular service called “CrmService” which will interact with the OData endpoint. Within the service definintion, we will use the $resource function to describe the REST service and define a custom “lookup” action.
The $resource function provides some built-in functionality to REST APIs for the standard HTTP methods. You can view the standard actions in the documentation. However with our CrmService, we are going to ignore those so that we can parameterize our custom lookup action by entity. Angular will automatically parse the route arguments in our lookup URL (entitySet, field, and search) as function parameters. Now we have a lookup service we can use in web resources.
Next we need to write the code to control our UI. This will be a small Angular app that has a controller to interact with the HTML. The controller will be responsible for calling our CrmService.
Here you can see we are just making a simple controller that will pass inputText to our lookup action. The request will be made asynchronously, so after Angular deserializes the response data for us, we can assign it to our controller’s $scope.
At this point you can see how easy it would be to change the entity or fields we want to perform the lookup on, or how to duplicate this call in other functions.
The last step is just a little bit of HTML to display our lookup results. The Angular directives (attributes that start with “ng-“) will take care of binding to our controller.
Adding “ng-app” to our <html> tag tells Angular to use our crmApp module in this file. The “ng-controller” directive on the <body> element scopes all child HTML elements to our AppController. By using “ng-change” and “ng-model”, we can bind the text value of the <input> tag to the inputText variable on our controller $scope, and react to the change event with our inputChanged function. Lastly, the “ng-repeat” directive will create a list item for every matched contact returned from our service, and a template expression will print out the contact’s name.
While the look and feel will need some additional work, you can hopefully see the benefits of using Angular with your CRM projects.
Note: AngularJS requires some special attention when working with Internet Explorer. There are a variety of syntax options for most features to help you avoid any issues with older versions of IE.
If you are building an editable custom Web Resource in CRM that will be embedded into a record form, typically you would want to make the Web Resource read-only when the record is deactivated. To do this, you would have your Web Resource check the form type and toggle between editable and read-only mode appropriately. In CRM 2011 this works great but in CRM 2013 you will notice that the form does not refresh after “Activate” or “Deactivate” in the Command Bar is used. Therefore your Web Resource doesn’t refresh and is still in the same mode that it was before.
Recently I had a chance to play with PersonAccounts while working on a project. If you’re unfamiliar with them, PersonAccounts are account records in Salesforce that act like Contacts, and even have the Contact custom fields available to them. They allow you to use the record almost anywhere you could use a Contact record or an Account record. This is especially useful for businesses that don’t really distinguish between Accounts and Contacts (like consumer facing retail stores), and would like to have the full functionality of native Accounts in Salesforce while retaining the common fields of Contacts like mobile phone numbers and home addresses.
In the particular scenario I was working in, the requirement was that whenever certain criteria happened on an Opportunity related to the PersonAccount, I needed to relate specific other PersonAccounts to the Opportunity based on some data in custom fields we had created. We planned on using the OpportunityContactRole native object to capture both which PersonAccounts should be related to the Opportunity and why (via the Role column).
Whenever I get a requirement like this, if I’m not sure about something I just attempt it through the UI first. I navigated to the Contact Roles related list on a test Opportunity and clicked the new button, which brought me to a screen where I could search for and select the test PersonAccount to relate to it:
After clicking save, I was returned to the Opportunity with the PersonAccount added:
No problems so far, so I started writing the code I thought I would need:
Seemed simple enough. Save and test:
So that definitely wasn’t what we wanted. Reading the error message closely we can see that the root cause is “Contact ID: id value of incorrect type”. What?! Why doesn’t this work when I just did the same thing through the UI?
After some head scratching and unsuccessful web searching, I decided to take a closer look at the records Salesforce was actually creating. There’s a neat trick in Firefox where if you hover over a link, it will tell you where the link will take you in the lower left. Hovering over the link in the related list on the opportunity gave me:
Notice the ID (highlighted) which starts with 003. I know from experience that the Account prefix is 001, so this seemed a little strange to me.
At this point, I decided to go back and review the documentation more carefully to see what I could dig up. Eventually, I found it: on the Account object’s page there’s a snippet towards the bottom detailing a field called PersonContactId, which is the ID of the ‘Contact’ that the PersonContact is ‘related to’. Firing up the developer console, I ran a query against this record to see what was in the database:
And there we have it, both IDs in one place. So what’s happening in the background is that Salesforce is using the PersonContactId to relate the PersonAccount record to the Opportunity instead of the ID field. Once I updated the code to use the Account.PersonContactId field instead of Account.Id all was well with the world again.
Need someone who knows the ins and outs of the Salesforce platform? Need a partner who can guide your project to success, and offer advice on best practices and change management? Just want someone to bounce ideas off of? Contact us and we can help.
Think there’s something we should cover but haven’t? Curious about some specific piece of the platform? Let us know in the comments below!
Definitions for change management in relationship to CRM vary widely from person to person. Every vendor has a different explanation of what change management is, and each client has a different expectation of what change management can do for them.
First things first. Sonoma Partners defines change management as the moving of processes, teams, and organizations to an alternative state. It’s a shake-up of your company’s current structure and way of doing things. It impacts many aspects of your organization including training, user adoption, and incentives for better employee performance. When done properly it can yield great results and improve your team’s organizational knowledge.
At Sonoma Partners, the term "change management" best describes the state of an organization before and after they have adopted a CRM.
A common (and dangerous) approach to change management is implementing a plan after the CRM system development comes to an end. This method may not give you the results, or user adoption rates, that you are hoping for. Disrupting the way your employees are used to working without their feedback or input up front may lead to you building a system that no-one will use.
A better approach to change management and CRM is to incorporate it into the conversation from the beginning of the project. Remember: if you’re giving real value to your end user, you are less likely to have issues with change management, because people will be motivated to use the new system.
Here are a few tips to help you build your change management plan:
Who in your organization is going to be affected? Outline and define value propositions for each party to motivate them to use the system after it’s built.
Engage all parties involved from the beginning. This includes executives, stakeholders, end users, and management.
Communicate how the new system works in relation to how each team member will use it. Create a communication plan that outlines the benefits, functionality and status of the project.
Formulate an answer to the following question: “What’s in it for us?” Your CRM project lives and dies by user adoption rates. Develop an incentive plan to encourage system use.
Change management is a lot like user adoption. It’s a term that is defined differently by every person implementing it, and every party looking for it. The best way to guarantee a successful rollout of change management is to build a CRM system for your end users that best suits their needs from the start.
A couple weeks ago I posted a video on the new Login Control that comes with the XRM Tooling library in the latest CRM 2013 SDK. Today I will show off another handy feature in the XRM Tooling library, the Web Resource Utility. The Web Resource Utility provides an easy way to retrieve an Image or XML web resource.
First you will need to download the latest SDK here. Then you can add the following namespaces:
using Microsoft.Xrm.Tooling.Connector; using Microsoft.Xrm.Tooling.WebResourceUtility;
Next you can either use the new Login control to get an instance of a CrmServiceClient or manually set it up yourself.
var crmSvc = new CrmServiceClient( CredentialCache.DefaultNetworkCredentials, AuthenticationType.AD, "server", "port", "org");
Then use the following code to retrieve an XML resource which will return a string of the XML content:
var xmlResources = new XmlResources(crmSvc); xmlResources.GetXmlFromCRMWebResource("myxmlresource.xml");
Or use the following code to retrieve an Image resource which will return a BitmapImage object:
var resources = new ImageResources(crmSvc); var bitmap = resources.GetImageFromCRMWebResource("myimageresource.png");
Now with the BitmapImage object, you could set an Image control directly within your WPF app and dynamically display images based off your web resources in CRM.
Recently I was working on a Salesforce1 mobile page and I ran in to an issue when attempting to use the sforce.one.createRecord API call. The code I started with was (condensed for brevity):
The idea here was to show the create record screen so that users could create a new Account when they clicked a button.
This worked fine on a desktop, but the createRecord call was a bit slow over cellular networks (on the order of 5 – 6 seconds to load sometimes). During this loading time, it looked like the page wasn’t doing anything so the users would click the button that fired this code multiple times, resulting in multiple new forms being shown. To prevent that, we added a loading layover that shows the first time the button is clicked, preventing the user from clicking it again.
So far this all worked fine, until we started really testing the create form. One of the things a user can do on the create form is click a cancel button which takes them to the previous form, where we got a nasty surprise: the loading screen is still there!
After some investigating, I found that the new Account form isn’t actually a new page, but is instead a layover on the current page, and the cancel button is just hiding the layover. Therefore, the custom page the user came from never gets reloaded.
We tried the onload event (which is only called when the page is loaded, not when cancel is clicked) and the onfocus event (which is only called if the user taps the screen again after clicking cancel). Neither were sufficient for us.
At this point, I opened a support case with Salesforce where they confirmed this is by design, and there is not a fix forthcoming.
We decided to take advantage of the fact that this is a layover and put in a timeout for the loading screen so the user isn’t permanently trapped. We added an idea to the Salesforce idea boards that you can upvote here if you think this is important to fix like we do.
I recently had a requirement on one of my projects to build a Visualforce page that summarized an event, including all of the attendees of the event. After doing some digging through the documentation, I found the EventRelation and EventWhoRelation standard objects provided by Salesforce. Reading through them, it sounded like the EventWhoRelation object best suited my needs, so I wrote the appropriate controller code to retrieve the attendees as follows:
This all worked fine, and when I tested the code through the UI I got back the results I was expecting. After I was satisfied with how it worked, I turned my attention to the unit tests to finish up. I started with the following code:
When I ran the unit tests, I saw the following logs:
Looking at the last line, there’s no Event Who Relations! Double checking the unit tests, I wasn’t running it as a particular user so I shouldn’t be getting any profile-related issues, and Shared Activities was enabled (otherwise EventWhoRelation wouldn’t be available at all), and I was using the latest API version available to the organization (31 as of this writing). The documentation says that EventWhoRelation is a filtered view of EventRelation, so I would expect that a record meeting the criteria listed (IsParent = true, IsWhat = false) to show up in the EventWhoRelation table.
I opened a support case with Salesforce to see what was going on here. After doing some digging on their end, they confirmed that the EventWhoRelation records are not created in test cases unless you add the @isTest(SeeAllData=true) attribute. Their explanation: since the EventWhoRelation is a derived table, we need to be able to see all data in the org to read from it (otherwise it’s just always empty).
We don’t typically condone using the SeeAllData setting unless absolutely necessary as it makes the tests more brittle and harder to maintain. The workaround I came up with is to not use the EventWhoRelation and instead use the EventRelation in my controller:
With the latest CRM 2013 SDK, Microsoft has provided a new XRM Tooling library to connect to CRM. Along with the new Tooling library comes a brand new Login control that is styled with the 2013 look and feel and can be used for custom WPF apps.
In our new video below, I demonstrate how to easily setup the new Login control so you can be on your way with your custom CRM WPF app.
- Visual Studio 2012 or 2013
- Latest CRM 2013 SDK - http://www.microsoft.com/en-us/download/details.aspx?id=40321
- NuGet Package Manager
We’re now at the point where enterprise mobility should be built into your CRM platform from the beginning of a project. You know that your sales team needs to be able to access their accounts and data on the go.
But how can you guarantee your users will have what they need when they need it? Build an app that nails these seven use cases to ensure that your sales team can and will use your mobile CRM application.
Don’t assume you are always connected to a network. The terrain that your sales team can cover varies and your app needs to be available every step of the way, regardless of possible nearby wifi networks or cellular connection signal strength. If your app doesn’t have the ability to record notes and orders offline and then immediately sync up when a connection is established, your sales team won’t use it in fear of losing valuable data.
#2. Brand Standards
When your sales team is meeting with prospects and customers they should be able to use their CRM app as a sales tool and collaborate directly with them. This includes being able to display specific product information, conduct a product demo and access relevant marketing collateral on the fly. Because your clients viewing your app with your sales team, your mobile CRM app needs to absolutely reflect your organization’s look and feel and reinforce brand standards.
#3. Digital Sales
Your team needs to be able to do more than pull up existing accounts in the field, they need to be able to create new ones! Your app must allow users to display and present sales collateral during client meetings. Most importantly you need to be able to pull up pertinent information relevant to a specific sale to get a holistic view of the account. Being able to check if merchandise is in stock or an updated version of an item is available could positively (or negatively!) impact the direction of a meeting.
#4. Location-Based Activity
As your team travels throughout the day they need to be able to see the accounts and prospects in the area. Incorporating geo-coding into your mobile CRM app can help your team maximize their time in the field. If a meeting is cancelled or postponed, being able to identify prospects geographically could translate to a new opportunity.
#5. Activity Management
Not only should your team be able to monitor clients and sales opportunities but they need to be able to manage their schedules. Build a mobile CRM app that allows users to track and manage their day including appointments, tasks, and to-do lists. Make this process as touch friendly and as simple as possible. Creating a tool that provides value and simplicity back to the sales team increases the likelihood of user adoption.
#6. Account Management
It’s important that your users are actually able to manage opportunities in the field.
Accessing sales materials and product information is essential to making the sale but taking notes, updating contact information, and adding reminders for future meetings can be just as important. Building a mobile app that allows your sales team to manage an account at all stages while in the sales process guarantees that the highest quality of data will make it into your CRM.
#7. Build an App that Minimizes Training
If you deploy an app that isn’t intuitive or user-friendly, we guarantee that your adoption rate will suffer. Remember that having to use your CRM isn’t enough of a motivation for your users, they have to need or want to use it. Engaging in a user discovery process and investing in thoughtful user experience increases the likelihood that your mobile CRM app will satisfy the needs and wants of your users.
Earlier this year, we posted an overview of Unified Service Desk based on a Convergence session. Now that the Spring ‘14 update has been released, get can get our hands on USD ourselves.
Note: This walkthrough is only meant for a development environment and should not be used for production.
First, head here to download the USD package. This contains a CRM2013-USD-PackageDeployer.exe and a UnifiedServiceDesk.msi. Run the msi which will install the actual USD desktop client onto your machine.
Next step is to run the CRM2013-USD-PackageDeployer.exe which will extract files to a specified folder. Navigate to the extracted folder and it should contain a PackageDeployer.exe. This is the new Package Deployer tool that we blogged about last week but it will already contain packages specific to USD. This tool will deploy solutions and import data to your organization so it is highly recommended to be done in a development environment.
Run the PackageDeployer.exe and you’ll come to a login screen. Enter credentials for the organization that you would like to install USD to and click Login.
Next you will get a list of package options to use. Select the package you would like to use and click next.
Clicking Next will move onto the next page that displays a detailed description of the package you are about to import into your organization.
Click Next to verify the organization you are installing to and then Next again and the tool will validate the solutions and import files that it is about to install.
Clicking Next again will start the import process and display a report of the status. If there are any errors, you can click the link at the bottom left to view the log file.
Clicking Next will display the completion page. Then click finish and you’re done with the installation process!
Now you can open the Unified Service Desk client that you installed in the first step. A login screen very similar to the Package Deployer tool will display. Enter your credentials to the organization that you installed USD to.
Now you can play around with USD in your organization and get a feel for what is possible. If you are interested in extending USD, head to MSDN where there is a great set of walkthroughs on adding custom modules, layouts, iframes, etc.
CRM Online Service Update 3 is being rolled out this week. To find out if your organization has been updated, click the gear in the top right corner and click About to check the build number. The build number for this update is 22.214.171.1243.
This update resolves a handful of issues both performance and usability related. Here are some of the most notable fixes:
- Duplicate records created if Save and Save and Close is pressed multiple times
- Unhandled exceptions in asynchronous plugin instantiation causes Async service to crash
- Option set not selected on first click
- SQL deadlock and performance issues after Spring Release ‘14 update was applied
- Multiple navigation and command bars show up via associated grid navigation
It is nice to see a steady release of fixes from Microsoft. Especially with a focus of frustrating usability issues and performance optimization. For a full list of fixes, check the KB article which can be found here.
In part 1 (Branding your mobile application) of this series we talked about how to brand the Salesforce1 mobile application to fit your company’s standards. In part 2 (Becoming mobile ready) we met Bob the sailorman salesman and customized the Salesforce organization to make it more mobile friendly. And in part 3 (Global Publisher Actions) we took a look at one of the ways you can add custom functionality to your Salesforce1 mobile deployment – by implementing Global Publisher Actions. In this 4th and final part of the series, we will take a look at one more way to add custom functionality to your Salesforce1 mobile deployment – Object-Specific Actions.
Object-Specific vs Global publisher actions
The main difference between Object-Specific and Global publisher actions is that Object-Specific publisher actions are context aware. They are invoked from a specific record using the publisher icon in the lower right corner of the SF1 mobile app (as opposed to the left hand navigation) and the code to make them work knows which record the user was on when they started the action.
This gives Object-Specific actions the ability to act upon the data contained in the record to perform various actions such as mapping the current Account using a maps application.
Bob is pretty happy with his mobile experience and has been adding Accounts to his VIP list which we built in the last part of this series, but the business is not as pleased. They’ve noticed that Bob has begun adding all of his Accounts to the VIP list, and would like to change the business requirements to have Bob also enter in a justification when he adds an Account to the VIP list. To enable this, we will build an Object-Specific publisher action for Accounts that Bob can use to promote them to his VIP list and enter the justification the business needs.
To do this, we will:
- Remove the VIP checkbox from the form
- Create a new custom field called ‘VIP Justification’ that will store Bob’s input. This will just be a long text field for now.
- Create and configure the Object-Specific action so that Bob can invoke it from an Account record.
- The action will take Bob to a new page which has the justification input field.
- When the page is submitted, the field is saved and the record’s VIP checkbox will be checked.
Step 1 – The customizations
At this point, these customizations should be old hat so I’ll just briefly go through what I did.
I created the new VIP Justification field on the Account object:
I created a workflow that sets the VIP checkbox to true whenever the Account is updated to have text in the VIP Justification text area:
And I updated the form to remove the VIP checkbox from it:
Step 2 – The Justification Page
Next, we need to create the page that will allow Bob to input his justification. Because we just need to display the text box for Bob to be able to input the text, we will use one of Salesforce’s native action types to display a form. We could, however, also write and deploy a custom Visualforce page like we did in the previous post to have more control over the look, feel and exact mechanics of the page.
For now, navigate to Setup > Customize > Accounts > Buttons, Link, and Actions and click New Action:
On the following page, enter in the following values:
The Update a Record type is what will allow us to create a form to present to Bob so that he can enter in his justification. Once he clicks save, the workflow we set up earlier will automatically check the VIP box – no code required!
Once you click Save, the next screen will be the form we want to present to Bob. Edit it so that it only contains the following fields:
Notice how we have to keep the Name field because it’s a required field. For our purposes, this is fine, but if we really didn’t want to display it we could write a custom Visualforce page that would track it in the background and only display the justification text box.
Before we save this, we need to make the Justification field required (no point in going to this page if you’re not going to enter anything…). To do this, hover over the VIP Justification field on the form so that the wrench icon appears, then click it. Next, click the Required checkbox and OK.
Once that is done, click Save.
Step 3 – Giving Bob access to the action.
The last thing we need to do is give Bob access to use the new action we just built. To do this, we need to edit his layout (the Standard User Layout) and add the action to it.
On the resulting page, click Actions in the header and drag the new Action we just created to the Publisher Actions section on the form. Click Save.
Step 4 – Testing it out
Now that we’ve given Bob access to the action, he should be able to start using it! Looking at Bob’s mobile device, we can see:
It’s our new action! If Bob clicks on it:
Bob is presented with the justification page we built. He can enter in a justification and click ‘Submit’ to add the Account to his VIP list.
This concludes our series on Salesforce1 Mobile. If you enjoyed it or found it useful, please let us know in the comments below!
Do you need help with your Salesforce deployment? Thinking about going mobile but aren’t sure what the best way to start is? Contact us! Our team of Salesforce and mobile professionals can help you from planning through deployment and post go-live support.
The Package Deployer is a new tool that was released with the CRM Spring ‘14 update and provides administrators with an easier way to deploy to CRM organizations. The Package Deployer can deploy one or more CRM solution files as well as import data and can even be extended to execute custom code to handle any edge cases while deploying to your CRM org.
Sounds great, so how do we get started? Well first, you will need to have Visual Studio (2012 or 2013) installed, which we be used to create a package. Next, download the latest SDK that was released with the Spring ‘14 update which can be found here. After the SDK is installed, browse to SDK\Templates folder and run the CRMSDKTemplates.vsix to install the necessary Visual Studio Templates.
Now that we have everything setup, we can start to build our deploy package.
- Open Visual Studio
- Go to File –> New –> Project
- Select CRM SDK Templates on the left
- Select CRM Package Deployment Template and click OK
This will create a structure in the Solution Explorer like shown below:
The PkgFolder is where you put any CRM Solution files that you would like to be deployed as well as any import data files.
In my example I have a solution “MySolution1” and “MySolution2” as well as a contacts.csv data import file.
Now you can open the ImportConfig.xml and update it with your package files. At the top of the config file you can also set if you want to install the out-of-the-box sample data as well as if you want to wait for the sample data to install before deploying your package. There are two agent desktop settings as well that can be used when deploying Unified Service Desk.
In my example I have the package deploying sample data as well as waiting for it to finish before deploying the package.
<configdatastorage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" installsampledata="true" waitforsampledatatoinstall="true" agentdesktopzipfile="" agentdesktopexename="" crmmigdataimportfile="">
In the solutions node you can define each of your solutions that should be deployed.
<solutions> <configsolutionfile solutionpackagefilename="MySolution1.zip" /> <configsolutionfile solutionpackagefilename="MySolution2.zip" /> </solutions>
Lastly, you can define any data import files to be imported with the deploy.
<filestoimport> <configimportfile filename="contacts.csv" filetype="CSV" associatedmap="" importtoentity="contact" datadelimiter="" fielddelimiter="comma" enableduplicatedetection="true" isfirstrowheader="true" isrecordownerateam="false" owneruser="" waitforimporttocomplete="true"/> </filestoimport>
That’s it for the ImportConfig.xml. Here is my full config for reference.
<?xml version="1.0" encoding="utf-16"?> <configdatastorage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" installsampledata="true" waitforsampledatatoinstall="true" agentdesktopzipfile="" agentdesktopexename="" crmmigdataimportfile=""> <solutions> <configsolutionfile solutionpackagefilename="MySolution1.zip" /> <configsolutionfile solutionpackagefilename="MySolution2.zip" /> </solutions> <filestoimport> <configimportfile filename="contacts.csv" filetype="CSV" associatedmap="" importtoentity="contact" datadelimiter="" fielddelimiter="comma" enableduplicatedetection="true" isfirstrowheader="true" isrecordownerateam="false" owneruser="" waitforimporttocomplete="true"/> </filestoimport> </configdatastorage>
One last thing to note is that the PkgFolder contains a Content folder with a WelcomeHtml and EndHtml folder. Within each of those folders are a Default.htm page. These pages can be customized to your needs to provide a unique welcome and end page during the deploy process.
Now you can build the solution in Visual Studio (Build –> Build Solution) which will create a dll that we will use for the Package Deployer Tool. Go to the bin\Debug folder, copy the PkgFolder as well as the dll named the same as your Visual Studio project and paste them into SDK\Tools\PackageDeployer.
Run the PackageDeployer.exe and a login screen will appear.
Select your organization and login. The next screen will display an iframe showing the content from the WelcomeHtml folder. As mentioned before, you can customize and brand the html page to suit your needs.
Click Next and you’ll see a screen that lists out the solutions and any files you have included to import.
Click Next again and the Package Deployer will attempt to import the included solutions and files. Once it is finished, it will give you a status on what succeeded or failed. You will also see another screen showing the content from the EndHtml folder which can be branded and customized as well just like the Welcome screen.
As you can see, the Package Deployer tool is a great asset for administrators and customizers. It is now easy to make your own branded installation wizard that covers most aspects of the deploy process so you can handle it in one fell swoop.
One mistake we see our customers make over and over again is comparing, and ultimately selecting, a CRM platform based on a list of features.
Often advertised as “new and improved”, CRM system feature lists include items such as: ease of integration, remote access, mobile access, integrated analytics, multi-channel support, and campaign management. If you’ve ever run a search for ‘CRM Features Checklist’ you could compile a list of dozens of “must-have” capabilities your CRM should include.
When it comes to selecting CRM software, basing the decision off of a list like this can be disastrous as features are updated at a rapid pace, and become outdated quickly.
Just how quickly are features updated?
Once an organization commits to a specific CRM platform, they typically will stick with that platform for AT LEAST 3 to 4 years before considering any type of switch. Every year, Salesforce.com pushes 3 major updates and Microsoft Dynamics offers multiple new releases as well. Let’s assume each new update includes several hundred new features. Doing some simple math:
- 4 year CRM platform lifespan
- 3 new releases per year
- 500 new features per release
- 6,000 NEW FEATURES!!
When you consider the CRM system you’re evaluating will have 6,000 new features over its lifespan, doesn’t it seem insane to perform a feature-by-feature comparison? The results of the shootout could be drastically different in just 3 or 6 months based on the product roadmap. Consequently, we think it’s futile (and potentially dangerous), to compare two CRM platforms on features as they exist today.
Here’s a not-so-little secret. At their core, ALL CRM platforms inherently share the essential features you need to get the results you want:
Giving your sales and marketing teams the ability to target your best customers? Check.
Optimizing information shared across departments? Check.
Accessing analytics to segment, analyze, and run reports on your business? Check.
Offering better customer service to build customer loyalty? Check.
So if we don’t recommend selecting your CRM platform based on today’s system features, you might be wondering “well then how should I select my CRM platform?” Glad you asked, we tackled this topic in a free eBook named the “The Ten Most Important CRM Evaluation Criteria”. You can learn more about the eBook and download it here.
The good news? As long as you pick one of the market leaders like Salesforce.com or Microsoft Dynamics CRM...either platform is flexible enough to be customized to meet your individual needs, regardless of how complex or unique you might think your business is. The real trick? Building a CRM platform that your sales team will use.
Determining if it’s time for your organization to invest in CRM software can be a challenge. However once you’ve come to the conclusion that yes, you need CRM software for your business, do you know the best time of the year to buy? Knowing the fiscal calendar information for both Salesforce.com and Microsoft Dynamics CRM might help you save a few bucks! Just like buying a car at the end of the month, quarter-end and year-end time periods mean that CRM salespeople are aggressively trying to close as many deals as possible to hit their own goals.
If you case you didn’t already know, Salesforce.com’s fiscal year starts on February 1st, and Microsoft’s fiscal year starts on July 1st.
End of the Quarter
If you’re ready to sign a contract but the end of the fiscal quarter is within arm’s reach, practice patience. As CRM vendors scramble to close out quarterly goals, recognize and take advantage of the opportunity you have to get a better deal on licensing and contract fees.
- Salesforce.com quarter-end dates: April 30, July 31, October 31
- Microsoft quarter-end dates: September 30, December 31, March 31
End of the Year
Similar to the end of the quarter mentality, waiting to sign your CRM software contract at the end of the year could land you in the sweet spot for cost. Year end is the absolute BEST time to negotiate yourself a great deal on your CRM software licenses.
- Salesforce.com year-end date: January 31
- Microsoft year-end date: June 30
Take Advantage of Offered Discounts
If you are working with a sales rep at Salesforce or Microsoft, please make sure to take advantage of the discounts they offer you when they offer them. We’ve seen situations where potential customers sit on a discount thinking they can get the same deal later. Unfortunately the quarter-end and year-end deals really do expire and some customers lose their discounts because they took too much time to make a decision. If you are ready to purchase, try to recognize a good deal when it’s handed to you!
When you’re planning your project, remember that the average project timeline with a CRM vendor takes 3-4 months from discovery to deployment. If you have an end date for when you would like your CRM to be up and running count backwards. Do your best to align your kick-off date with calendar to get the best rate for your CRM software and implementation.
Enterprise mobility is your sales teams’ lifeblood.
Being connected even when lacking a connection, is essential for productivity and getting the job done. The best way to ensure that your team has the tools they need at their disposal is to build them a CRM app with enterprise mobility.
To demonstrate how important mobility is, we’ve outlined a typical day in the life of a sales person on the move and mobile dependent. I want you to meet Phil.
Phil has 6 years of in-the-field sales experience working with a global manufacturing company. Let’s walk through a day in the life of Phil to grasp how essential CRM mobility is for him to successfully complete his day-to-day tasks.
It really begins the night before.
These days, the day begins at midnight. 95% of people (and I’m going to guess that a majority of your team doesn’t fall into the other 5%) bring their gadgets to bed; tapping, swiping, and browsing the web before they begin their slumber. It’s likely that the last thing they see before they go to bed is the glowing screen in their palm. It should be effortless to transition between their CRM and the apps they need to plan their day.
In Phil’s case, he starts preparing for the next morning’s meetings the night before. He confirms appointment times in his CRM and quickly takes a look at his weather app to see if he needs to plan for a longer commute.
Good morning, Phil.
A few hours later, the alarm goes off and the screen is glowing again. Phil takes another quick pass at his emails that have arrived overnight and checks his favorite websites, both professional and personal. He opens his CRM system and confirms his meetings for the day. It looks like he has 3 appointments and everything is set to run as planned. He rolls out of bed and starts prepping for his first meeting over breakfast.
The first meeting includes a new product demo with a potential customer. He checks the client’s profile in the CRM and notes that this account is hot- they are so close to closing the deal! Phil does a run-through of the demo to make sure everything is running smoothly and that he has the notes on the new features that came out last week. He also runs a report on the product’s inventory to make sure that the model the prospect is looking at is in stock.
Phil sees the afternoon is booked with current customers. He pulls up their existing profiles and orders and checks to see if any of their product lines have been updated. He also sees that it’s one of his client’s birthdays so he makes a mental note to ask about their plans to celebrate the big day.
The mid-day check-in.
The morning meeting went better than expected. The prospect was blown away by the product demo and they gave Phil a verbal approval for a purchase order! Phil makes notes directly into the CRM during the meeting. He takes notes about the questions they have in order to update his FAQ page. The entire sales team is responsible for recording customer’s concerns, questions, and insights after their meetings. Because his CRM includes a field for client’s notes he can easily tap in the responses without disturbing the natural flow of the meeting.
Because the customer wants to get products in stock right away, Phil is able to place the order from the conference table. He confirms which items are in stock and which ones have a longer turn-around time. The ordering process moved quickly because of the smart fields built into the order form. Phil simply keys in the company’s name and the rest of the contact, billing, and shipping information fills automatically. Another benefit of using the CRM to prepare and manage an appointment.
Phil heads to the second appointment of the day.
He knows that he is meeting his contact at a lab in a basement and service is non-existent. Because his CRM saves all information he enters offline and syncs it back up when he reconnects he doesn’t need to switch to pen and paper to take notes.
The customer gives Phil her opinion on a new product she tested and he takes notes in real-time. Before using a mobile app, he was required to take these notes on paper and then had to rewrite them in the CRM on his desktop. Phil admits that the quality of his data before he got his hands on the mobile app were sub-par and the relationship with his clients sometimes suffered because of it.
Being unprepared for a sales meeting is unacceptable. With the current technology landscape, clients expect to be able to see the product you’re trying to sell as you’re trying to sell it. Because Phil has all of the tools in the palm of his hands, he is never concerned about being underprepared for a meeting.
The late afternoon.
Phil’s third appointment had to cancel because of a conflict. He checks tomorrow’s schedule before reaching out and notices he has an appointment with another prospect 3 miles away. He sends a follow up email, requesting to meet the following afternoon and the client obliges.
Because of geo-coding capabilities built into the CRM, Phil can organize his schedule based on locations. With the afternoon wide open, he decides to stop by another client’s office and drop off some free product samples. Because Phil can easily access his records via his mobile CRM application, he doesn’t waste any time adjusting his schedule and completing a task off his to-do list.
Enterprise mobility is your sales teams’ lifeblood. Are you 100% sure that your CRM system supports your sales team's needs? If not, please contact us. We can help you get them the mobile tools they need!
In part 1 (Branding your mobile application) of this series we talked about how to brand the Salesforce1 mobile application to fit your company’s standards, and in part 2 (Becoming mobile ready) we met Bob the sailorman salesman and customized the Salesforce organization to make it more mobile friendly. Today, we’re going to look at how to extend the organization beyond what comes out of the box by looking at the primary way you introduce new functionality to your mobile users: publisher actions.
Publisher Actions – Extending your reach
Publisher actions are ways of adding additional actions that your users can take to the Salesforce1 mobile (and full) application. They can be context sensitive (called object-specific) that work with specific records, such as an action that logs a call related to the current Account, or they can be context insensitive (called global) that do not deal with any record in particular, such as an overview page or global map. Both types of actions have their places and are useful in different circumstances and we’ll cover both in turn. Today, we’ll focus on global publisher actions, how they work, and how to create a new action of your very own.
The Return of Bob
Bob has been using the customizations we made for him for a few weeks now and is happy with the changes. However, he has now started thinking about a new way to prioritize some of his customers. Bob would like to be able to track his Accounts that are very important to him and to be able to access them from quickly on his mobile device. To do this, we’re going to build a VIP list page for Bob and push the update to his mobile device so he can start using it right away.
For the time being, the checkbox to make an Account a VIP will be on the Account form itself.
Here’s the basics of how we’re going to approach this:
- We will add a custom field to Accounts called VIP that is a checkbox. If the checkbox is checked, then the Account is a VIP and should show up on the page that we will build.
- We will build a custom page that retrieves all VIP Accounts owned by the current user and displays them in a list. Clicking on a record will take you to the details of that record.
- We will expose this page in such a way that Bob can quickly access it the mobile application.
Step 1 – Add Custom Fields
This part should be pretty straightforward, so I won’t spend a lot of time going over it. We’ll add the checkbox to the Account object, add the field to the forms and update a few records to have the VIP status set.
Step 2 – The VIP Page
Now that we have the fields in place, and some data set up, we can create the custom page that Bob will use to access his VIP list. The resulting page will look something like:
To create this page, a developer will need to write some simple Visualforce and Apex code and upload it to the organization. The code will consist of two parts: the Apex controller which controls what data will be displayed, and the Visualforce page which controls how the data is displayed. I won’t go over the code line by line, but if you’re interested you can see the source code in this Github repository.
Step 3 – Exposing it to the mobile application
Once the code has been uploaded to the organization, we need to give Bob’s profile access to use the new code. We do this by navigating to the Standard User profile (Bob’s profile) and adding access to the appropriate pages:
Next, we need to tell Salesforce that this Visualforce page is ready to be used in the Salesforce1 mobile application. We can do this by going to Setup > Develop > Pages > Edit
On the following page, check the box to enable Available for Salesforce mobile apps:
Now that our Visualforce page is Salesforce1 mobile ready, we need to create a global publisher action that will use it. To do that, we go to Setup > Create > Global Actions
After clicking New Action, we select the Action Type to be a Custom Visualforce page, Select our VIP List Visualforce page, and give it a label (the Height isn’t really needed since we’re using a Visualforce page).
Next, we need to edit the global publisher layout to include the new publisher action we created. In our case, we’ll create a new layout from the native one, edit it, and assign it to Bob’s profile. This will leave all other users’ global layouts intact, while giving Bob the functionality he needs. To do this, we go to Setup > Customize > Chatter > Publisher Layouts
On the next page, click New and select the Global Layout to copy from:
I chose to name this new layout Standard User Global Layout. Click Save. The resulting page shows you what actions have been included by default:
Bob doesn’t actually need all of these actions, so we’ll modify his global layout to only include the actions he needs, including the new one we just built:
Finally, we need to assign the layout we just created to Bob’s profile. Click Publisher Layout Assignment and edit the assignments so that Standard User uses the Standard User Global Layout:
And that’s it. Bob should now be able to see and use the new action we just created for him. Back on Bob’s device, when Bob is on the feed (the default page when the mobile app starts up) and he clicks the publisher icon, he will see the new action available to him:
If Bob clicks on one of the records, he’ll be taken to the record’s details page:
The great thing about building actions like this is that we’re not constrained to putting them on the feed page. By editing the forms, we can also add the action to the various record forms, or we can create a Visualforce tab and use the Visualforce page we built to expose this page to the users through the left-hand navigation on the mobile device. All without changing any code in the page itself!
Obviously the page we built today is very simple and just a demonstration of what can be done. The pages can become as complex as needed to fit your use case, and can be embedded in multiple locations to provide convenient access to the functionality as needed.
Are you looking to expand your Salesforce mobile functionality, and need help getting started? Don’t have developers to write the code? Have questions about mobility in general? Contact us and we can help.
Today's guest blogger is Jacob Cynamon-Murphy, a Sales Engineer at Sonoma Partners.
Let’s say you found yourself in a situation where you have two different CRM platforms running within your company. One group is using Salesforce.com and an entirely different group runs Microsoft Dynamics CRM. How did you get here? Maybe you had a renegade in the sales office or you're handling the result of a recent merger. Regardless of how you got here, what do you do now?
Good news - you have choices. Whether you choose to consolidate to one system, create an integration bridge between the two, or "live and let live" with two disparate systems, we can help you make the best of a tenuous situation. From a high level, we see primarily three different options on how to handle these multiple CRM system scenarios:
Where do you start? We believe that consolidation is the best approach if there is substantial overlap between:
the data in the two systems
the majority of functionality is duplicated between the two systems
the users of the two systems collaborate very closely or frequently
Integration makes sense if the two systems represent distinct phases of a business process, and there is limited overlap between the records in the two systems, but each system shares key data (such as accounts or contacts).
Example: You use Salesforce.com for lead acquisition and qualification and Dynamics CRM for opportunity management or product/service delivery. In this case, you may not need each member of your organization to be licensed in both systems and could instead create differentiated roles. This solution will keep licensing costs and maintenance efforts down.
Lastly, segregation might be the right option for you. If there is little to no overlap of users or data, there may be no impetus to have the systems talk to one another or, even more drastic, consolidated into a single platform.
One example of this is when one system is used for a completely custom capability, like learning management or HR, while the other system is used for the more conventional CRM scenarios of marketing, sales, and service. Although you end up with two different systems to support and maintain, you don't have to navigate the paths of integration or consolidation.
Now that you understand the basics of each of the three approaches, we want to share some additional thoughts for managing each path.
Let’s assume that you've decided that consolidation is the best approach to address your multiple CRM systems – this means consolidating multiple CRM systems into a single system, and the prior systems cease to exist.
At Sonoma Partners, we find most client choose this approach. Let's talk about what you need to keep in mind when electing consolidation.
#1: Merging Data - Odds are that you have a lot of overlapping or conflicting data, so your first step will be to complete a thorough analysis of your data. You need to identify duplicate records and the best approach to de-duplicate. Often that approach is a merge, but you may have reason to default to the records in one system or the other as "better data."
In any case, it is often best to extract your data from the CRM systems and use staging tables to store the data as you merge, manipulate, and cleanse your records. Without diving into detail, you should know that there are a handful of third-party tools you can use to avoid having to manage this manually.
#2: Reducing User Licenses - One potential benefit of consolidating CRM systems is that you might be able to reduce the number of CRM user licenses you need to pay for! However, when going through a consolidation, identify if the subordinate (i.e. "going away") system has a license expiration date that is prior to the cutover date. You want to avoid falling out of licensing compliance. Since most CRM contracts have annual or multi-year commitments, don’t expect any CRM vendor to offer short-term contracts so you need to plan accordingly.
#3: Integrating with Other Systems - Each of your CRM systems may already be integrated with other line-of-business applications. It is best to review each system and determine where other critical systems are integrated. Before you decommission the subordinate system, you'll want to reproduce any critical integrations into the new master CRM (i.e. "sticking around").
#4: Decommissioning Legacy Apps or Integrations - As part of this process, it's beneficial to review all of the legacy enhancements, add-ons, extensions, and integrations with both the subordinate CRM and the master CRM. Especially if two different groups were developing these solutions in a vacuum, your business may have invested resources in building duplicate features or producing/purchasing an enhancement that the master CRM can do natively. Alternatively, it's possible that the subordinate system could do something natively that you will need to configure or purchase for the master CRM to address the need going forward.
As you can imagine, it's best to know where you are headed before you start down the path of consolidation. The tips above should help you find your way.
Now let’s assume you've selected integration as the best approach to address your multiple CRM systems. Taking this path means you’ve agreed to maintaining more than one CRM system. In addition to managing the licenses, your CRM administrator(s) will also need to manage multiple platforms and user bases. If you go this route, here is what you need to keep in mind.
#1: Choosing an Integration Tool - There are a variety of integration platforms that can talk to multiple CRM systems - Scribe, Informatica, SQL Server Integration Services (with the appropriate connector), and Dell Boomi, to name a few. If you already have a preferred integration tool, and it supports your CRM systems, you really don't need to make a decision. However, if you don't currently have an integration tool in use, take some time to evaluate the options. Some key decision-making criteria you can use are: price, platforms supported, deployment model (is the tool an on-premise installation or is it SaaS), and does your team have existing skills to support the platform or would training be necessary.
#2: Determining System of Record - Since you have made the decision to maintain more than one platform, you need to determine which system, if either, will serve as the system of record (i.e. master data). Occasionally, you will already have another system, ERP perhaps, that serves in this role; in that case, both other systems may be subordinate to that system of record. If you do not already have a de facto system of record, think about which system is used more frequently or is more likely to have higher quality data. It is even possible that you will choose one system to be the master for some data (e.g. companies and contacts) and the other system master for other records (sales data or customer care records, for instance).
#3: Mapping the Data - A DBA or data architect will be indispensable at this stage. When mapping the data, you need a thorough understanding of the data schemes in both systems, which records or record types are 1-to-1 between the systems, and which fields (data columns) correspond between the records. The map defined here will ultimately feed into the integration setup stage, below.
#4: Setting Up the Integration - This is where the rubber meets the road. The best advice I can give you here is to define the integration mappings in your selected integration platform and run them against test instances of both platforms. Salesforce.com and Dynamics CRM Online both offer sandbox and test instances you can leverage and Dynamics CRM 2013 (on-premise deployment) offers the ability to export the full SQL database for import into a DEV or TEST server; for other CRM platforms your mileage may vary.
This scenario offers less opportunity for strategic planning or tactical decision-making as the integration and consolidation approaches probably will. Customers who want a global view of accounts might not like this situation at all. Likewise, running multiple CRM systems means IT needs to duplicate some effort to manage multiple vendors. This includes keeping the right skills on staff, managing multiple roadmaps, negotiating licenses, renewals,etc.
On the plus side, CRM system segregation does offer some benefits that might appeal to certain companies:
You can designate different system administrators for each system so you don’t have to worry about “too many cooks in the kitchen”.
Related to this, IT can probably be more responsive to the business needs since they only need to worry about their own system. They don’t need to discuss system changes or customizations with other departments or groups.
Administrators have more opportunity to really tweak each CRM system to meet the user’s individual needs. Changing forms for different users is easy enough, but having entirely different systems allows administrators to get more aggressive with other things such as field names, currency, languages, etc.
Very little to zero change management to worry about, users keep running their existing CRM systems as-is. No interruption to the business.
Having multiple CRM systems in your organization might work for some companies, but definitely not everyone.
Another variation of segregation is to consolidate some parts of the data from both systems into a reporting system or data warehouse. This approach allows organizations to have true global reporting across multiple systems, but obviously it requires additional work to setup the reporting infrastructure.
In summary, organizations have lots of different options on how they want to handle the multiple CRM platform decision. The “right answer” for your organization, might not be the same answer for a different organization because you should consider many different factors before deciding whether to consolidate, integrate or segregate. Our hope is that this post will give you some food for thought and peace of mind as you work through this situation. As always, feel free to contact us if you need additional advice – we’re happy to help.