Product Schedule in Salesforce

In Sales Cloud, when companies are dealing with Accounts, Contacts, Opportunities and Products, one thing is very obvious who the company will get the money back from the Contacts for the Products sold to them. Are the contact/account going to pay all together in one shot or are they going to pay over the period of times(Equal Installments)? 

Salesforce has the answer to these questions. In Salesforce you can configure how your customer will pay you the money. Based on that configuration, you can run your business reports to track your sales matrices. The way you can configure this in Salesforce is known as Product Schedule. Product Schedule are the payment or delivery cycles for the products which will be either paid over time or delivered over time. 

In Salesforce we have three different types of schedules. 
  • Quantity Schedule: Choose this schedule when you want your products to be delivered over the period of time. Example - Consider your customer bought subscription of one magazine from you for the next 2 years. Now you need to courier the monthly subscription to your customer every month. So in this scenario, you will go for Quantity Schedule.
  • Revenue Schedule: Choose this schedule when you want your customer to be billed over the period of time. Example - Consider you are selling House Insurance to your customer. The total cost is USD 1200 for one year. But you will bill customer on monthly basis i.e. USD 100 per month. In this scenario, you will go for Revenue Schedule.
  • Revenue and Quantity Schedule: Choose this schedule when a product will be delivered over the period of time and you bill your customer also over the time. Example - Consider your customer bought the subscription of one magazine for next 2 years. But this time instead of charging your customer at the beginning, you will charge the customer on monthly basis and also courier the magazine on monthly basis. In this scenario, you will go for Revenue and Quantity Schedule.
Schedule Type:
Schedule Type defines how the Number of Installments is used. There are two types of Schedule Type 
  • Divide: Here the Unit Price is divided by the number of installments.
  • Repeat: Here the Unit Price is multiplied by the number of installments.
Product Schedule can be enabled from Setup > Customize > Products > Product Schedules Settings.

Note - Read this post from Salesforce on Consideration for using Product Schedules.

Default Schedule:
A default schedule is associated with a product for a particular price book. Every time such product is added to the Opportunity, the default schedule is automatically added as well. Even though default schedule is automatically added to the Opportunity, Sales Rep can still change the schedule. 

Let's go for some Use Cases.

Use Case # 1
Company ABCD is selling subscription of their magazine - "Let's Enjoy". This magazine is getting published on monthly basis and cost of each publication is USD 10.00. Company ABCD is having customer who is planning to buy the subscription for next 2 years. Sales Rep of ABCD will now create the opportunity, add the product and product schedule as well.

Assumption: Product "Let's Enjoy" is having no default schedule setup.
Product is configured as shown below -
Now create the opportunity and add the product to the opportunity as shown below -

Let's configure the Product Schedule now as shown below in the below pictures -

So now Quantity Schedule is configured in Salesforce.

Use Case # 2
Company MNOP is selling "House Insurance". Cost of House Insurance is USD 1200 per year. Company wants to bill customer for this insurance on monthly basis. Sales Rep of MNOP will now create the opportunity, add the product and product schedule as well.

Product is configured as shown below -
Now create the opportunity and add the product to the opportunity as shown below -

Let's configure the Product Schedule now as shown below in the below pictures -
So now Revenue Schedule is configured and the total amount i.e. USD 1200 is divided into 12 equal monthly payments i.e. USD 100.00.

Note - If a product is having both default Quantity and Revenue Schedule, then Quantity Schedule is calculated first to determine the total product revenue. Then the Revenue Schedule is applied to the amount. I will explain this in my next Use Case.

Use Case # 3
Company IJKL is selling Medicine Box (Cost is USD 10.00 per box) to hospital BCD. The quantity of Medicine Box is 1000. Company will deliver the boxes over the period of 12 months on monthly basis. Company will send the bill to hospital quarterly over the period of 6 installments. Sales Rep of IJKL will now create the opportunity, add the product and product schedule as well.

Product is configured as shown below -

Now create the opportunity and add the product to the opportunity as shown below -

Default Schedule will be applied and it will be displayed as -

As the above picture says, the quantity is distributed on monthly basis where the revenue is distributed on quarterly basis.

I hope with the above examples, the concept - Product Schedule will be easy for you to understand. Please provide your feedback. Thanks.

Relationship between Product, Price Book and PricebookEntry

In my previous post, I have explained the basic concepts about Products and PriceBooks. You can read the post here - Products and Price Books in Salesforce.

Now in this post, I am going to explain the relationship between Product, Price Book and PricebookEntry. So let's start with few basics.

  • Products are represented by Standard Object - Product2.
  • PriceBooks are represented by Standard Object - Pricebook2
  • Each Pricebook can have zero or more entries. Each of these entries are stored inside the Standard Object - PricebookEntry. Each entry in PricebookEntry defines the cost of the products in a particular currency.
  • These three objects - Product2, Pricebook2 and PricebookEntry will only be available if Product is enabled in the organization.
Data Model:
  • PricebookEntry is the junction object between Product and Price Book.
  • OpportunityLineItem is the junction object between Opportunity and PricebookEntry.

Below is the flow diagram depicting the process to load Products and setup PriceBook through API.

I hope this post will help you to understand the relationships between these objects. Please provide your feedback. Thanks.

Products and Price Books in Salesforce

Define your Product:
A Product is a service or item that the company sells to the customers. Once you have added the Products, you can set the price of the product per unit based on your business. In Salesforce, Product is a Standard object having standard fields and tabs. You can add your custom fields to customize Product object as per your business requirement. Products can be added to the Opportunity allowing you to have an correct inventory and also make your forecasting accurate.

What is Price Book:
The Price Book will provide the list of products and their prices per unit. You can create multiple price books to maintain different prices for the same product based on your business needs. Salesforce will always provide your a Standard Price Book. The moment you add a Product into Salesforce and set the price of the Product, that Product will go into Standard Price Book. But you can create Custom Price Book as well.

Use case of Custom Price Book:
Let's say, the company "Universal Company" is selling the product - "Desktop Mouse" globally. The company is running it's business from Canada. But company is selling products globally. Now when this company is selling "Desktop Mouse" within Canada, the price is USD 12.00, but when it is selling the same product in Europe, the price is USD 19.00 (due to extra shipping cost), similarly then the same product will be sold in APAC, the price will be USD 20.00. Now to maintain different prices for the same product based on geography, we need to create three different Custom Price Books - Canada Price Book, Europe Price Book and APAC Price Book.

Don't worry, I will provide you the entire step by step configuration in later part of this post. Let's concentrate on the basic concepts and considerations while configuring Products and Price Books in Salesforce.

Important Notes on Creating Products:
  • Permission needed to create Products are "read" and "create" permission on Product object.
  • You can create Products by cloning an existing Product. But if you don't have sharing access in any of the Price Books, then entries for that Price Book and Product combination will not be created. Similarly if you have read-only access on any fields, value of that field will not be carried over to the cloned record.
  • It is recommended to not have more than 2,000,000 products otherwise it may impact the performance.
  • Products always needs an active Price Book so that you can add the product to that Price Book.
  • Product object is having a standard field - Product Currency. This field holds the currency of the product. In a multi currency organization, if the product currency is different from user's currency, then product currency will be converted into user's currency and both the values will be displayed. (Converted amount will be displayed in parentheses).
Sharing Price Books:
  • Admin or user with with "Edit" permission on Price Book can share the same with more users, groups, roles and territories.
  • You can't make it more restrictive.
  • Sharing option will only be available when the OWD of Price Book is either "No Access" or "View Only".
  • Price Book Sharing is not available under Salesforce Lightning Experience(Latest release is Spring'17 when I am writing this blog post). It is available only in Salesforce Classic.
Want to remove Price Books? Need to know below points -
  • You can delete, deactivate or archive Custom Price Books. It is having no impact on other Custom Price Books. These action will impact Opportunity and Quotes.
  • You need to change association with Opportunity or Quotes before removing an associated Price Book.
  • For Standard Price Book, you can deactivate the same, but can't delete or achieve it.
  • You can't delete a Price Book while it's in use on Opportunities or Quotes. Trying to do the same will create a list of Opportunities or Quotes where the Price Book is being used.
  • You can deactivate a Price Book while it is being used in Opportunities or Quotes. Managing Entries is also possible for deactivated Price Books and you can re-activate the same as well.
  • You can archive a Price Book even if it being used in Opportunities or Quotes. Archived or Deleted Price Books can't be recovered.
Want to remove Products from Price Books?
  • You can remove Products from a Price Book as long as that Price Book + Product combination is not being used in any existing Opportunity or Quotes. Removing Products from a Price Book will not impact other Price Books where the same Products are listed as well.
  • If a Product + Price Book combination is being used in any of the existing Opportunity or Quotes and you want to remove the Product from that Price Book, you have three options, which is explained here - 
Important Note - While associating Products with an Opportunity, you need to select the Price Book first. An Opportunity can have Products only from one Price Book.

Use Case:
The company "Universal Company" is selling three products - Mouse, Monitor and Laptop. The price of each Products is different for each Geography. The detail is displayed below -

Implementation -
  • Create three different Products in Salesforce with Standard Price and add them in Standard Price Book as shown below - 
  • Now create three different Price Books and add the products there with the corresponding prices as shown below - 
In my next post, I will explain the relationship between Price Book, Product and PricebookEntry. Please let me know your feedback. Thanks.


Delegate Administrator

In a big organization, a single admin can a big problem in terms of bandwidth issues. Normally admins are getting multiple requests like - creating users, updating profiles, resetting the password, running report etc. along with their daily meetings. So it will be really difficult for a single admin to handle all these requests by himself/herself. And that is the place where admins want to delegate some of their work to others (trusted colleagues). But trust me, it is a big decision. You should not give all the admin privilege to your colleagues even though he/she is a very trusted employee. Rather you should delegate few specific task to your colleagues. In Salesforce, we can do the same with DELEGATE ADMINISTRATION.

So basically Delegate Administrator will allow named users to manage other users within selected roles and profiles, as well as managed selected custom objects.

With Delegate Administration, you can configure named users to do the below things -

  • Role & Subordinate:  Delegate Administrator can create and edit users with specific roles and subordinates. The can't modify the role hierarchy though.
  • Profile:  Delegate Administrator can assign users(they create or edit) to assigned profiles. They can't modify the profile.
  • Permission Set: Delegate Administrator can add/remove selected permission sets from users(they create or edit) to assigned profiles. They can't modify the permission set.
  • Public Group: Delegate Administrator can add/remove selected public groups from users(they create or edit) to assigned profiles. They can't modify the public group.
  • Custom Object: Delegate Administrator can manage every aspect of the selected custom objects except object's permission on profiles. Delegate Admin can't create or modify relationship on the objects or set org-side sharing defaults.
  • Enable Login Access: Delegate Administrator can login in as a user belonging to the role hierarchy that they manage.
  • Unlock and Freeze User.
To make an existing user as "Delegate Administrator", you need "Customize Application" Permission and that user need "View Setup and Configuration" permission.

Note - "View Setup and Configuration" permission is always a tricky one as it will open up many  more permissions to the users. So before giving this permission to any user, you should think multiple times and justify yourself. Giving "View Setup and Configuration" permission to a user so that you can mark that user as Delegate Admin should NOT be the correct approach. I will highly recommend you to read the post - "Become More Efficient With Delegated Administrators" from AdminHero.

Use Case:
I have two users in my Org - Administrator (Sudipta Deb) and Non-Administrator(Mario Ruiz). I want to mark Mario as Delegate Administrator so that he can take care of creating/editing users with Profile - "Recruiter" or with the role - "VP, North America Sales". At the same time, I would like to make sure he can take some of the request related to custom objects - Position, Job Application, Employment Website, Job Posting.

  • Open Delegate Administration: Click on Setup | Administer | Security Controls | Delegate Administration.
  • Click on New
  • Put the below details as shown in the picture -
  • In the next page, under "User Administration", select the role - "VP, North America Sales" like shown below - 
  • In the next page, under "Assignable Profiles", select the profile- "Recruiter" like shown below 
  • In the next page, under "Custom Object Administration", select the objects - "Position, Job Application, Employment Website, Job Posting" like shown below - 
  • Add the user "Mario Ruiz" under "Delegated Administrator
  • Finally, it will look like - 

There are few limitations as well with Delegate Administrator which are -
  • Can't assign profiles or permission sets with "Modify All Data" permission.
  • The -None- option will not be available when selecting roles for new users.
  • For formula fields, accessing merge fields from another object requires delegate admin's permission on that object.
  • Can't modify permission sets.
  • Standard Objects are excluded from Delegated Administration. We have a Salesforce Idea open for this - https://success.salesforce.com/ideaView?id=08730000000BptIAAS
  • Another Salesforce Idea worth mentioning here is - Allowing Non-Admin users to import custom objects - https://success.salesforce.com/ideaView?id=08730000000Bre6
  • For security, profiles with the “Modify All Data” permission cannot be included under "Assignable Profiles". See the error when attempting to include the System Administrator profile. 
  • Delegate Admin can change the FLS for existing and newly created fields for those objects which are assigned to him/her. But Delegate Admin can't change the Object Level Permission on Profile.
Are you using Delegate Administrator in your org? What use case you are handling using Delegate Administrator? What problem(if any) you faced? Please share your feedback. 

JavaScript Tips for Visualforce Developers

When I started my career 10 years back, I was first introduced to Server Side Programming. I started developing applications using Embedded C/C++. Slowly I shifted my focus towards Client Side Programming. It always motivates me if I see the end-result of my development immediately. That is how I started digging into Client Side Programmings. I always love this below quote from one of my favorite programmers - Eric Elliott

In my initial days I still remember, it was really difficult to learn JavaScript. To me, Javascript was more like a "side" language which can help implementing those functionalities which can't be delivered by server side programming - such as DOM manipulations, browser events and things like that. So for me sending data between server and client was always a GET and POST.

But I realized the power of JavaScript very soon. Trust me, with JavaScript, you can do so many things you can't even imagine. You can not only do Client Side operations, you can perform server-side logics as well. Yes, you hear it correctly. JavaScript for Server Side Programming. With the "node.js"  you can perform server-side computations as well. But there is even more. We can now build Isomorphic applications as well. With an Isomorphic application, your initial request from the web browser will be handled by the server, but after that, any subsequent requests will be handled by the client. I will not get into the detail of isomorphic applications here. That will take the entire blog post, which is not the intention here. You can check the details about the Isomorphic application here.

We all know that Salesforce introduced Lightning which is the new way of developing applications using aura framework. Now you can build Lightning components which can be used to build SPA(Single Page Application), Record Detail Pages, Home Pages etc. Lightning brings a development paradigm shift from traditional Visualforce+Apex centric development. But as we all know Visualforce is very matured and there are so many customers using Visualforce to build/enhance their applications. So Visualforce is definitely not going away. But as per the recent trend from Salesforce, it seems like most of the new features will be delivered in Lightning (That is now the main focus area of Salesforce) and bug fixes/critical enhancement will be delivered for Visualforce. But since Visualforce is not going anyway and I know there are so many customers which still feel more comfortable with Visualforce page, so putting your effort to learn Visualforce page still makes sense to me. With Visualforce, customizing the application as per customer's branding and requirement sometimes become really a challenging work and we need to take the help of JavaScript and other model JavaScript libraries like Jquery, AngularJs etc.

So I would like to share my experience regarding working with JavaScript and Visualforce page. Let's get started -

Tip # 1 - Learn JavaScript
There is no alternative of learning JavaScript. There are many resources available which you can utilize to learn as well as enhance your JavaScript knowledge. I am sharing few of them below -
Along with learning JavaScript, you should learn some browser tools as well. Chrome DevTools for Chrome browser is probably the most used tools. With Chrome DevTools you can use some of the really advanced as well as helpful features such as - Interactive Debugging, Inspect Elements, Device Emulation, Performance Profilings, JavaScript CPU Profiling etc.

Tip # 2 - Put your JavaScript in Static Resource
As per best practice, you should put your JavaScript in Static Resource. It will minimize the load time of the page. You can access JavaScript from Static Resource in the below way -

We have some real advantages by putting JavaScript in Static Resources. We all are familiar with merge syntax in JavaScript like below -

The above code looks very simple. But the there is a catch, by putting the above line we are making the JavaScript tightly coupled with VisualForce rendering. By tightly coupled, I mean if due to some reason the JavaScript is not processed by Visualforce rending engine, then the merge syntax will not be evaluated and in the Visualforce page it will be displayed as {!Case.CaseNumber} instead of the actual value.

If we move the JavaScript in Static Resource, then the same JavaScript will be loaded as an external file to the browser and browser will cache the external file. This means for every call, JavaScript will not be delivered to the browser, rather browser will use the cached JavaScript. External files are always included once the VisualForce page is finished rendering and delivered to the browser. So by adding JavaScripts in Static Resource, they will be delivered as an External file to the browser and those JavaScripts will be processed by the browser, not the VisualForce rendering engine.

I will always say that while doing development, you can keep your JavaScripts in the VisualForce page rather than in Static Resource. It will help you to debug and fix the issues quickly. But once this is done, please move all your JavaScript in Static Resource.

Tip # 3 - Avoid Cross-Site Scripting Issues
A developer should always use JSENCODE and JSINHTMLENCODE functions which will help to prevent cross-site scripting. Consider the below code:

Here if the value of the parameter emailAddress is alert('Your account is hacked!!'), then the above code will execute the JavaScript function. In the same way, any JavaScript can be executed to fetch some important information. To stop that we should use the JSENCODE function like below -

To learn more about Injection Vulnerability Prevention, please go through the below trailhead link -

Tip # 4 - Go For an Efficient Development Process
Working with JavaScript and Visualforce sometimes makes the life of a developer difficult as you need to change JavaScript to solve issues, zip it and upload the same and then test. And this process you may need to repeat quite a  number of times. If you also face this same issue like me, then I would like to let you know that MavensMate has a solution for you i.e. resource bundles. Resource Bundles will allow you to direct editing of the files and makes the uploading process very easy. There are some tools as well which can help you as well like grunt or gulp. But I feel MavensMate is very easy to start with. Grunt and Gulp are more for the advanced stage.

Tip # 5 - Keep an eye on variable declaration
Always use JavaScript object and put all your variables inside those objects. This will help you to make sure that your declared variables are not getting overwritten by Global Namespace i.e. window object. So you should declare your variables always like -

Bonus Tips
A developer should read the best practices for JavaScript related in Visualforce Developer Guide.

With all the above tips, I hope it will help you to write efficient JavaScript code. Please let me know your comments. Thanks.

Never miss a post. Subscribe to get latest blog posts, right into your email box.

* indicates required


Salesforce (105) Apex (52) admin (28) visualforce (21) ADM (20) dev 501 (19) lightning (19) integration (18) learn salesforce (18) 501 (16) javascript (14) SOAP (13) tutorial (11) Advanced Apex (10) Certification. (10) Kitchener Developer Group (8) Trigger (8) test class (8) Certification (7) flow (7) security (7) unit testing (7) Advanced Admin (6) Lightning Experience (6) SOQL (6) Sharing and Visibility (6) design pattern (6) developer (6) report (6) salesforce release (6) service cloud (6) trailhead (6) use case (6) Lightning Feature (5) New Features (5) css (5) dashboard (5) debug (5) formula (5) mobile (5) solution management (5) JSON (4) Kitchener User Group (4) Knowledge Management (4) Lightning Web Component (4) New Feature (4) Sales Cloud (4) Salesforce DX (4) Tips (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) event (4) github (4) html (4) map (4) polymer (4) profiles (4) release (4) responsive (4) tdd (4) ui (4) visual studio code (4) Architect (3) Article (3) Live Chat (3) Online Event (3) Opportunity (3) Performance (3) Products (3) REST (3) Role (3) SOSL (3) Salesforce Certification (3) Scratch Org (3) Spring 20 (3) Study Notes. (3) Summer15 (3) VS Code (3) Web Technology (3) Winter21 (3) automation tool (3) configuration (3) dynamic apex (3) license (3) mapbox (3) singleton (3) version controlling (3) AppExchange (2) Asynchronous Apex (2) Asynchronous callout (2) Aura Framework (2) Bulkify (2) Community (2) Data Architecture and Management Certification (2) Devops (2) Distributed Version Controlling (2) ES6 (2) Eclipse (2) Einstein (2) Enhancement (2) Enterprise Territory Management (2) Financial Services Cloud (2) Force.com IDE (2) Governor Limit (2) Groups (2) IBM (2) Implicit Sharing (2) JourneyToCTA (2) LWC (2) Lightning Design System (2) Live Agent (2) Metadata (2) PD II (2) Price Book (2) Queueable (2) SFDX (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) Virtual Event (2) ant (2) basic (2) chatter (2) code coverage (2) coding (2) communication (2) console (2) controller (2) documentation (2) dreamforce (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) salesforce1 (2) strategy (2) visual workflow (2) xml (2) Action Plan (1) Action Plan Template (1) Activity Timeline (1) Advanced Currency (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) Arrow (1) Batch (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Celebration (1) Cheat Sheet (1) Classic (1) Compare (1) Confetti (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) CumulusCI (1) Custom Metadata (1) Custom Object (1) Custom Permission (1) Customer (1) Data Model (1) DataCategories (1) DataGrid (1) DataTable (1) Dated Exchange Rate (1) Decorator Design Pattern (1) Dev Hub (1) Development (1) Diwali (1) EDA (1) ESLint (1) Education Cloud (1) Email (1) FSC (1) Function (1) Future (1) Global Gathering (1) Goals (1) Guest Access (1) Guest Profile (1) Guest User Sharing Rule (1) Guide (1) HEDA (1) Higher Education (1) Household (1) Husky (1) IDE (1) Ideas (1) Improvement (1) Invocable (1) KPIs (1) Knowledge (1) Large Data Volume (1) LastModifiedDate (1) Lightning Knowledge (1) Manage Currencies (1) Manual Sharing (1) Metrics (1) Multi Currency (1) New (1) OOPS (1) OWD (1) Omni-Channel (1) Optimize (1) Partner (1) Permission Set (1) Person Account (1) Photo (1) Pipeline (1) Platform Developer I (1) Platform Developer II (1) Presentation (1) Prettier (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) QuickReference (1) Related records (1) Reports (1) Retrieve (1) Role Hierarchy (1) SAL (1) Salesfor (1) Salesforce Advisor Link (1) Salesforce Labs (1) Salesforce Optimizer (1) SalesforceDx (1) Schedule (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) Summer19 (1) Switch (1) SystemModStamp (1) Tile (1) Timeline (1) Unauthorized Access (1) User License (1) Users (1) Validation Rule (1) Web (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) actionFunction (1) actionPoller (1) actionRegion (1) actionSupport (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) cli (1) code (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) duplicate (1) dynamic (1) dynamic form (1) email template (1) email-to-case (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) solution (1) sub-tab (1) survey (1) tab (1) username (1) workflow (1)

Popular Posts

Total Pageviews

Contact Me


Email *

Message *