Ok folks, here’s a challenge. You have a customer who runs a car dealership. You’ve got Salesforce Professional Edition, 8 weeks, little-to-no budget, and plenty of hungry sales reps with tons of leads that have to be managed. From lead to cash. From the first call to giving away keys to a brand new shiny vehicle. Would you even go for a project like this?
About the Company
The company which I’m writing about is called TC Motors. It is a Subaru, Dodge, Jeep, and RAM dealer located in the eastern European country of Latvia. It has 25 employees and is more than 25 years in the automotive business.
The Company is making money by selling new cars and offers car maintenance services. The whole process which I will be talking about in this article is limited to the new car sales process. From Lead to Cash.
This means the Salesforce org I’m talking about, is capable of tracking the customer from the moment it schedules a visit on the website (or any other place) to the moment a sales rep is handing over the keys for a brand new shiny car to the client.
How It Started
The story began last year in April 2021. I was escaping Covid restrictions in Spain with my wife and a kid when a lead landed into my corporate Salesforce account…which I have successfully missed.
Two months a lead was just sitting there as an unattended record and I was happily living with my other projects. That ended when I decided to check my filters in CRM and noticed that I was filtering out all the leads from one particular landing page on our website. Fortunately, there was only this one, which I have missed.
So two months after my customer left an inquiry on our website, red like a tomato and full of shame I picked up the phone and gave a call to the prospect. I will intentionally skip the part where I’ve been explaining to a potential customer why CRM guys like me are missing leads. But this is how the story started.
Project Limitations
After I’ve set up a discovery meeting I’ve immediately run into a dilemma. Whether I should get involved in this project or not. And here’s why:
- The project had a tiny budget, which usually represents some minor changes to our regular customer’s setup.
- The customer was happy to pay only for Salesforce Professional Edition (which was the biggest challenge, and I’ll explain why later)
- The company was short on time because they were to launch seasonal clearance before New Year.
So this doesn’t sound like a great deal and in other circumstances, I would avoid getting involved in such projects, however, it was not the case.
The Dealbreaker
The project was way too interesting to resist. The customer had a lot of ideas and we immediately found a common language. I liked the idea to experiment with Professional Edition, which was not possible in our other projects because of their complexity.
Secondly, The company had one huge excel file full of formulas, indicating a very clear picture of what had to be done. Honestly, I’ve never seen such a great systematization of processes in a single excel file. The idea of replicating excel with Salesforce and making someone’s life easier caught me.
Last, but not least, the customer agreed I can make this case fully exposed to the public except for confidential data, of course. So I’ve decided to give it a try and see what happens. I’ve also decided to take full responsibility for the project on my own without attracting my colleagues from other departments. This means – I have had to design a fully fledged CRM for car dealers without writing a single line of code. Simply because I’m not capable of that.
As you might guess, I decided to buy-in. To do the project with Professional Edition.
The Great and Terrible: Sales Cloud Professional Edition
So, what’s so special about it? I’m not sure whether ever in your life you came across the Salesforce Sales Cloud Professional edition, but hopefully not. I honestly had no idea what I was getting myself into before I actually started to build the project.
Professional Edition is reasonably priced and offers plenty of opportunities for the small company like my customer is running. On paper, it offers everything you could potentially need. However, there are two MAJOR limitations, which are a pain in the bottom part of the body which I will talk about later.
The Great
Let me start with what Salesforce is selling to its customers on the Professional Edition.
- Price. 75 bucks per user. Reasonable.
- 50 custom objects (vs 100 in Enterprise Edition)
- 100 custom fields per object (vs 500 in Enterprise Edition)
- 3 custom record types per object (vs Unlimited in Enterprise)
- 5 Flows per Flow type (remember this, we’ll get back here)
- 5 Processes in Process builder (which just extends Flow limitations slightly)
- Person account option (arguable, but useful in my case)
And plenty of other default bells and whistles like chatter, Jurassic Park of standard objects, roles & permissions (which are also limited to 10 profiles BTW), unlimited number of records etc.
Special thanks for the Einstein Activity Capture, which works great and extends the functionality of this artificially limited version of SFDC.
The Terrible
What’s missing and is desperately wanted in a nutshell:
- Approval processes
- API
- Dataloader desktop version
- Flow & Process quantity (limited to 5 per type)
Remember I’ve mentioned the limitation of 5 Flows per type and 5 processes in Process Builder. Here is a rhetoric question for Salesforce Consultants. Could you imagine building 50 different objects with 100 fields per object with only 5 Flows for the WHOLE org? I could not. Probably Salesforce has a different view on this.
As I have already mentioned, Professional Edition is missing API, which in turn results in the following limitations:
- Inability to install most popular free plugins (and paid) in AppExchange, simply because they rely on API.
and most importantly
- Inability to use Dataloader (I’m talking about the desktop version, online works just fine) results in limiting your system to manual data entry and/or updating 50k records in one batch via Data Import Wizard. And what a surprise – Data Import Wizard does not work with all standard objects.
At the end of the day, you are buying a standalone CRM that is incapable of connecting to other systems which is unthinkable in 2022. And moreover, it’s incapable of playing around with data even inside the Salesforce itself because you have only five Flows per type and you are limited in terms of how much data you can pull back and forth across the system.
Oh, and special credit to Quotes object developers in Salesforce. They deserve a separate pot in hell, but I’ll get back to this later.
Project Requirements
I will not be listing detailed project requirements here, because…I didn’t have them clearly stated before the project. Due to the budget limitations, we’ve agreed with the client that we are going to stop at some point when the budget runs out, but with the help of the professionals at TrustMyPaper, we’ve listed an MVP concept, and here’s what we came up with.
Lead Management
A customer has more than 20 different Lead sources and he wanted to track where leads are coming from. Later, the lead source could help understand which of the sources resulted in the most sales (successfully won opportunities). That way customers can decide where most effort should be invested and which lead sources to prioritize.
Also, depending on the lead source, lead scoring could be affected. Knowing which sources show the best results, a higher priority for leads coming from highly performing sources could be assigned.
Opportunity Management
Arguably, the most sophisticated and resource-intensive part of any customer acquisition and sales process is Opportunity management. As I’ve mentioned before, TC Motors is selling new vehicles, which means they are doing test drives, configuring vehicles for customers, tracking vehicle stock, issuing offers, and many other things. In short, here’s what we’ve decided to take care about during the implementation of the project:
- Opportunity stage management
- Test drive management
- Leasing inquiry management
- Invoice & Payment tracking
- Offer management
- Order Management
Vehicle Lifecycle Tracking
Any dealership is managing a new vehicle lifecycle. Should they use excel or specialized software – all of them are tracking warehouse availability, what’s coming to the warehouse, ordering new vehicles from the manufacturer, tracking warranty period, and many other different details about the vehicle. So here is what we needed to implement:
- Vehicle Status Management
- Vehicle Availability for Sale
- Vehicle Financials (Price Tag vs Sales Price, Sales rep commissions etc.)
- General vehicle management (license plate number, warranty period etc.)
Order Management
Order management is a critical part of any car dealership’s business. In order to track and manage orders, they need a system that can handle the following:
- Tracking when an order is placed
- Tracking the stages of an order (e.g. pending, in progress, completed)
- Tracking the items in order (which I’ll discuss in a more detail later in this article).
- Ability to track invoices and payments
Reports
Of course the reporting part could not have been left apart. Below is the list of reports that we’ve decided to build:
- Lead source report
- Vehicle stock report
- Order tracking report
- General vehicle management (license plate number, warranty period etc.)
- Order general report (including invoice/payments)
- Tracking when an order is placed
- Tracking the stages of an order (e.g. pending, in progress, completed)
- Tracking the items in order
And many more…
Spare Part Database
One last thing we wanted to implement was a simple database for car spare parts. We wanted to import an excel file that contains 1m+ spare parts with prices, so sales reps could have quick access to the database, but unfortunately, I didn’t make it due to a lack of ability to import 1m+ number of records into the Professional edition without splitting the file into 50k records.
Roles
Now the final part, before I proceed to the overall architecture of the system, is to describe roles on the projects.
If you ever have implemented any customer relationship management systems into small companies, you’ve probably noted how many roles with very few employees these companies have. TC Motors was not an exclusion. The company had 5 roles for 5 users which was unacceptable so I’ve shrunk them to two:
- The Manager – owner of the system with the rights of admin
- Sales rep – standard user profile with wide access to records, but without ability to admin the system.
Simple as that. I could go into more details, however, because those different roles are affecting the system and its architecture, but we’ll get there later in this article.
Another note here. I’ve made my best effort to make this automotive CRM as scalable as possible. Roles could be added later and thanks to clear separation of data by objects it would be relatively easy to split roles without going much into field-level security.
Objects
It’s time to talk about high-level architecture of the system, objects and their roles in the process. I will go in random order, which however represents the consecutiveness of the process, so expect me to tell you about the process as we go through the objects inside Salesforce. The only exclusion will be the custom object in this org – Vehicles. This object is in the core of the reporting and aggregates most critical business information.
Vehicles
Due to the fact that the company has been selling cars for the last two and a half decades, their process has been built around vehicles which they are selling. Even in the excel file which represented the process in the pre-salesforce era of this company, the vehicle was in the first column while the customer was at the end of an endless spreadsheet.
As a result, I was simply unable to ignore this ideology and have created a custom object which has 74 custom fields. I will not list all of the fields, but will tell you about the group of the fields instead.
And before we begin. The whole reporting in the CRM is built around vehicles, so this object is used everywhere else and collects information about the deal as an opportunity progresses and converts to order later.
General Details
First group of fields contain Make, Model Year, Model Code, Package and other critical details about the car itself and its packaging from the factory.
Technical Data
This group of fields represent such data as VIN number, Warranty Expiration date, Radio Code etc. This acts like as a lookup book when a vehicle (in case it’s sold) arrives at the service station. That way service agents can take a quick look and get reference details about the car to look it up further in other systems like Subaru database or RAM international warranty program.
Invoicing & Delivery
This group of fields contain information about purchasing of the car (not sale) by a dealer. What is arrival date, when it was invoiced and what is car’s stock number. This information is used by CEO to make sure no invoices are not missed and to plan revenue flows by the financial director.
Cost Information
Here is where the most fun happens. In TC Motors Salesforce org there is a comprehensive area with cost calculation of the car, any discounts provided by the manufacturer, first registration fees and taxes charged by government when the vehicle get registered for the first time.
Sale Information
The most complicated part. There are fields which are related to calculating actual car sale price, including extra options. This area is later used for reporting and employee incentives calculation.
Bonus Information
This area contains information about sales rep who actually have made the sale and incentives company has to pay out to an employee based on the sale information.
That being said, it’s time to move to the next object.
Status field
As mentioned in the requirements, the company had to track the lifecycle of the vehicle and I’ve done this by simple status field shown in Path. There are four statuses for each vehicle:
- In Production
- In Transit
- In Stock
- In Operation
Status of the vehicle affects how the vehicle appears in various lookup forms across this automobile CRM software.
Leads
Sales CRM is not thinkable without Leads object. The whole process starts here, but there is not much special I could tell you about Leads. Apart from few custom fields and field mapping with opportunities, there were not many changes. Except the fact that during the conversion process the user is capable of creating Person Account (which is activated for this org) or Organization Account.
Accounts
As I have mentioned before, this SF org has a personal account activated. This makes life a lot easier when it comes to GDPR compliance and tracking of the contacts. Most automotive sales are done with private persons, so person accounts fit more than perfectly in the paradigm of this particular setup.
Accounts have a Generate PDF button, which launches HIC Docs Made Easy plugin to generate GDPR consent for the customer to sign. This prevents sales reps from making those documents in Word.
Once doc is signed, sales rep than takes a photo of the signed document, uploads it to the Account and it is being stored there for an indefinite amount of time (or until deleted as required by GDPR and particular customer preferences)
Opportunities
As you might guess, Opportunities are one of the key objects in this Salesforce Org. They store information about….opportunity. What’s interesting in this case, is that I did not create any custom fields for Oppys. I have removed most of the fields and left only Close Date, Amount, Probability, Stage and a few technical fields which are necessary to link records to other records, which we will discuss later.
The reason why Opportunities do not have many fields is because they heavily rely on related objects. For example, during the sales process Sales rep could set up test drives which are represented by custom Object – Test Drives and so on. (Patience, I’ll go through every object in the system)
Test Drives
As mentioned before, Test Drives custom object represents test drives and it is master-detail related to Opportunities. It stores information about date, time, driver license information and is related to account, opportunity and vehicle. Vehicle information inside a test drive custom object is used for two purposes. First of all, to fill in all the fields inside a PDF template which is being signed by a customer before each test drive (contract, insurance etc.). And secondly to track which vehicles are most heavily used in test drives.
Another role which Test Drives custom object plays in the sales process is tracking actual test drive status and creating calendar events. Once the test drive is completed, the sales rep has to click on a custom button to fill in the information about test drive results, how customers felt and what feedback sales rep have collected. Once filled in all the fields, Flow posts information to chatter on the related Opportunity page, so next time a sales rep opens Opportunity he can immediately see the history of test drives and his own comments to this Oppy.
And finally, the decision to make a custom object rather than use a custom calendar record type was due to reporting and status history tracking. There is a plan to implement a separate KPI for the test drives per each sales rep in the long run.
Leasing Inquiries & Invoices
I have created another custom object which was designed to serve one particular goal similar to cases in Salesforce. There is a dedicated manager in the company who is responsible for issuing invoices and communicating with banks in regards to customers leasing inquiries.
Side note. Customers do not like to share sensitive financial information with their sales reps, however they are fine talking to dedicated leasing managers. That’s another reason to put aside leasing inquiries and prevent sales reps from seeing this area.
This custom object has two record types. One for leasing inquiries and another for invoice inquiries.
- Leasing inquiries contain information about the vehicle, its sales price and customer details, so the leasing manager could get in touch with customers without actually opening an Account or Contact record. It simply pulls all the data via formula fields into one place for the user convenience.
- Invoice inquiries are just like invoice inquiries, but they act as an intermediate object between Invoice object (described later) and Opportunity. This is needed because Salesforce is not connected to the ERP system and invoices have to be raised manually and reference information is being written to Salesforce manually.
Both record types have status and in both cases statuses are translated to the Opportunity layout for sales reps to be capable of tracking status of their inquiry.
There is a screen Flow in place in order to create Leasing Inquiries & Invoices records. I will discuss all Flows used in this Salesforce org in a separate paragraph, but here it is used to make the process of inquiry preparation easier and more linear and to prevent double entry of the data by the user.
Invoices
Invoices in this Salesforce org represent actual invoices raised to the customers. They have information about price and ERP invoice number for reference. All of the data is coming from the ERP system but is entered manually.
One of the main goals when designing this custom object was to make sure that sales reps will be able to track how many invoices are raised for their customers and what is the total value of invoices.
This object has a lookup to Opportunity, so it’s very easy to create an Invoice from an Opportunity page layout. I’ve also created a custom button on Leasing Inquiries & Invoices object to quickly create Invoice records. User has only to enter Invoice number from the ERP, all other fields are populated automatically.
Payments
Payments are master-detail related objects to Invoices. I’ve made this object to track payments for the invoices.
Interesting about payments is that payments could be tracked via cash payment or trade-ins. This is represented by two record types on the Payment object and depending on how the accountant (or senior sales rep) is willing to capture the payment, they should pick corresponding record type and type in relevant information.
Quotes
Now we have come to the most heavily used Object in the whole Salesforce org for this customer – the Quotes.
I have very controversial thoughts on this object in Salesforce. On one hand Quotes are great because they could be hard-tied to the opportunity, sync products and easily be duplicated if at least one quote is synced to the opportunity. On the other hand, they add additional layers to drill down for the user which doesn’t add up to a user friendly interface.
If you have never worked with Quotes objects on the Salesforce, you will have to learn how product, price lists and quote syncing works in Salesforce before you proceed any further. It is out of the scope of this article to explain Salesforce standard functionality.
Quotes could be raised with a single click of a button within Opportunity object via custom button, which runs ScreenFlow, pre-populates all mandatory fields and automatically syncs newly created quotes with Opportunity. This prevents user from doing stupid work of inventing quote name (why it could not be replaced with Quote number? Ask Salesforce devs). Once screen flow is done, which literally takes less than a second, the user is shown a link to a newly created quote which is open in a new tab.
I’m not sure it’s the right place to whine about the Quote Line Item creation interface and its terrible limitations on customization, but I should say one thing. I’ve invented a bicycle twice to reduce the amount of effort for users to input products, pull picklist values for the line items and generate correct pricing. Again, I’ve used flow and process builder, which I’m discussing later in this article in a specially dedicated area.
Products & Price Books
Also I’ve customized Product objects and have created two custom record types, plus I’ve created a Flow to populate Price Book records, so users don’t have to create Price Book entries or edit them separately. They have standard pricing for all customers, so there is no need in creating multiple price lists.
Their sale price is being calculated based on Product cost and installation costs. These numbers are later used for order processing and vehicle financials calculation. I’ll get back to more details in the Flow description part of this article.
Orders
And finally, I have heavily modified the Orders object to align it with the process. It contains lots of relations with invoices, payment, vehicles, opportunity and uses Order Product Lines to translate this into Vehicle custom object.
His Majesty Salesforce Flow
Now we’ve come to the most interesting part of my story. And most technical. If you are not a developer (or salesforce consultant), I suggest you stop reading this article at this point.
The Process
Before we jump into details, I wanted to share a MIRO board with you guys where I have described the whole process from Lead-to-Cash.
The process is not described in a conventional BPM format, but is Object oriented instead. I’ve made it that way, because it will give you some clarity over the process and how the process moves from one object to another as the deal progresses.
Just make sure that you are reading the diagram from left to right and zoom enough to see transitions between stages.
Created Flows
Flow is one of the most powerful features Salesforce has to offer. It’s essentially a visual programming language which could be used to automate business processes. In this Salesforce org, I’ve used Flow for the following purposes:
- Screen Flow – Create New Quote
- Screen Flow – Create New Leasing or Invoice Inquiry
- Screen Flow – Create New Order (Opportunity Conversion to Order)
- Autolaunched Flow – Update Vehicle Sales Information
- Autolaunched Flow – Update Order Payment Summaries
Created Processes with Process Builder
I’m also including Process Builder here, which most likely is going to be depreciated in the nearest future and I’ll have to convert these processes to Flows. For now, I have used process builder, because of the limit of 5 flows per type. In my case, it’s kind of cheating and extending functionality with process builder, in case you wonder why I would not go exclusively with Flow.
Here’s a list of Processes, (I’ll deep dive into every process later):
- Record Change – Apply discount and Installation costs
- Record Change – Create New Event when Test Drive record is created
- Record Change – Generate Price Book Entry
- Record Change – Send Leasing Inquiry Notification
- Record Change – Update Invoice Status
Screen Flows
Now it’s time to deep dive into every flow I’ve created in this project. I will start with screen Flows and will move to Autolaunched flows later.
Create New Quote
Fairly simple flow. What I’ve tried to achieve was simplify the most heavily used functionality within the system. When sales reps were creating quotes from related lists they had to fill in the fields, which had to be filled with the same logic every single time.
So I’ve decided to simplify. What happens here, is the user clicks a custom button on the Opportunity page and voila – a new Quote has been created.
Flow has several simple nodes. What it does is:
- Create New Quote and populate all mandatory fields
- Sync quote with Opportunity, so every newly created quote is automatically synced with Opportunity.
Create New Leasing or Invoice Inquiry
Another simple screen flow, however compared with previous one it has several complexities.
- It won’t allow user to create leasing or invoice inquiry if there is active test drive in progress
- I’ve placed this screen flow into the lightning interface tab, so the user have immediate access, and there are no unnecessary button on the top of the Opportunity record page.
- Depending on the account type, which is related to Opportunity, it will fill in the registration or personal code to the account card. The user only has to input information to one field and doesn’t have to think.
- It will pre-fill fields from the related account record if information about address is already there. If changes are made, it will update related records.
- A quote has to be picked. It will be used as a basis for the invoice/leasing inquiry and will determine default invoice amount value on the next step
- Now user needs to pick inquiry type, pick vehicle which is going to be part of an inquiry
Click finish, and we’re done.
Now let’s jump into what happens in the background.
This flow doesn’t fit onto one screen, even if I minimize the size of the browser screen.
Let me know in the comments down below this article, if you are missing descriptions for the Flow, and what kind of descriptions you are missing, so I could update the post.
Create New Order
Now I have slowly come to the most sophisticated Flow of the whole system. This flow is at the core of all reporting and the reason why TC Motors have started this project.
“Create New Order” Flow is working in close connection with another flow called “Update Vehicle Sales Information”. As a result, this automotive CRM gets a report about vehicle sale price and how much money the dealership has made as a result of the sale.
This is a screen Flow, and it makes several checks before it runs any action in order to make sure that Opportunity is cleaned up before it gets closed and all reports will show perfectly correct data.
- First it checks if there is a quote synced with Opportunity.
- Then it checks if there are any test drives in progress.
- Then it checks if the quote has a vehicle related to every of its quote line items.
In order to launch the Flow, the user has to pick it on the lightning interface tab.
Then it has to pick the right quote which is used for creating order product lines and correct sale prices.
Flow shows the message to the user informing them about what is going to happen next.
In case a vehicle, which has been linked to the product line item was already sold, it will show an error message.
The next important step is to link quote line items to vehicles. This is needed to tell the flow which line items have to be calculated towards which vehicle. For example if we have multiple vehicles on the quote, then this will help separate different line items for various vehicles.
If line items have not been already assigned during the quoting process then Flow will ask for each line to which vehicle this particular line item corresponds to.
This screen flow uses lookup from the quote object and filters out sold vehicles, so that users could not pick the vehicle which has been already sold.
What I did was, to make user life easier, when you choose a vehicle once, every next screen will pre-load the vehicle chosen on the previous screen.
The last screen before actually creating an order is to choose the delivery deadline (when the vehicle has to be delivered to the customer) and add extra costs. Extra costs field represents costs incurred for particular order and if order contains more than one vehicle, then those extra costs will be spread evenly across all vehicles in the order and translated to vehicle object.
The last screen informs the user that the order has been successfully created. At this point Opportunity is Closed Won and the quote which was used for the order creation is marked as Accepted. If Opportunity had multiple quotes, all other quotes are marked declined.
Last but not least, below is a screenshot of the flow. In case you are interested in more details, just write the comments down below under this article.
Autolaunched Flows
It is also important to mention Flows which work in the background to make sure that the customer relationship management system collects and stores data properly. In particular, there is one critically important Flow, which I will be talking about below.
Update Vehicle Sales Information
This flow calculates Vehicle Sales information (just like the name says) every time Order is updated. What it does is separates vehicle order lines versus accessories (additional part, tuning, options etc.) and summarizes them on the vehicle page.
Below is a screenshot of the Flow itself.
Due to the fact that it has to read all line items, looks are used in the flow, to go through every line item on the order.
Update Order Payment Summaries
This flow was created because I could not create rollup-summary fields for non master-detail relationships. I could not link an invoice to the order, because often an invoice is populated before an order has been actually created, so I’m translating invoice and payment values to the order using this Flow.