Dynamics 365 version 9.0
The out of the box pricing logic in Dynamics 365 Project Service Automation is Role based. Bookable Resource (in most cases a synonym for a User) based pricing is something that is asked a lot so I decided to investigate this subject in more detail. When a Time Entry is submitted, Journal Lines for both Cost and Unbilled Sales are created followed by Actuals on an entry’s approval. Achieving Bookable Resource based pricing is quite simple and can be achieved with a no-code solution by editing Journal Lines when they are created. If you only want to see the functionality described in this blog post in use, you can jump all the way to the bottom of this blog post and watch the video.
Why is Bookable Resource specific pricing desirable? One of the most common arguments is subcontracting. Organizations may use subcontractors who use PSA’s Time Entry to submit the hours they have done. Their Role in PSA may be defined as “Subcontractor” however the pricing between subcontractors can vary. Instead of creating different Roles for Subcontractor 1, Subcontractor 2 etc, we can simply price each subcontractor individually and then use Roles to further categorize our subcontractors. As multidimensional pricing in PSA is still in the future to come, combining Bookable Resource specific pricing with Roles is needed in many cases to overcome the limitation of the OOTB Role based pricing.
Considerations before customizing Dynamics 365 Project Service Automation
Enabling Bookable Resource based pricing is fairly simple and this blog post will walk you though the steps to achieve it. Before getting started, I want to emphasize that we are customizing and editing Journal Lines which are, together with Actuals, the heart of all financial data in PSA. Incorrect Journal Lines and Actuals will lead to incorrect financial data so I encourage you to properly test these customizations in a development environment and each time you update Dynamics 365 Customer Engagement and the PSA solution. Using a managed solution for these customizations should be considered as you can easily uninstall them if needed.
The big picture of the necessary customizations
The customizations covered in this blog post are made on the Bookable Resource, Project Approval and Journal Line entities. The reason the Journal Line entity needs to be customized is because of PSA’s OOTB logic. One would reason that setting the Sales and Cost Prices on Project Approval by a workflow would suffice but this is not the case. Cost Journal Line aside and on the date of this post, a value set to the Sales Price field msdyn_salesprice on Project Approval by using a workflow will not flow to the field Price msdyn_price on an Unbilled Sales Journal Line.
Customizations on Project Approval set the Sales Price field to match a Bookable Resource specific price from Bookable Resource. The original Sales Price on Project Approval and the Cost Price from Bookable Resource are stored in custom fields so that past approvals can be reviewed when necessary. Changing the pricing logic between Bookable Resource specific and Role specific is enabled on Project Approval.
The customizations on the Journal Line entity serve a straightforward purpose of setting the correct value to the Price and Amount fields on Cost and Unbilled Sales Journal Lines. When the Journal Lines are updated, the Actuals following an approved Time Entry will have the desired values on them.
Stage 1 – Customizations on Bookable Resource
Goals of stage 1:
– Fields with Bookable Resource specific sales and cost prices are created.
– Possibility to set Bookable Resource specific pricing to Yes or No.
Bookable Resource is at the center of the configurations. The Sales and Cost Prices are set for each Bookable Resource to get both Project Approvals and Journal Lines populated with the desired prices.
Use Bookable Resource specific pricing is a field that controls if Bookable Resource specific pricing is to be used. If this field is set to No, all submitted Time Entries will use the OOTB Role based pricing.
1. Create a Two Option field, a Sales Price field and a Cost Price field.
2. Create a Quick View form and include the fields from the previous step as well as the OOTB name field on the form. The Quick View is used on Project Approval later on.
Stage 2 – Customizations on Project Approval (optional)
Goals of stage 2:
– Show Bookable Resource specific Sales Price on Sales Price msdyn_salesprice if conditions are met.
– Show related information from entity Bookable Resource to determine if Bookable Resource specific pricing is set to Yes or No.
– Allow the user to change the pricing logic between Role specific and Bookable Resource specific based on what is selected on the Use Bookable Resource specific pricing field on Bookable Resource.
– Allow the user to change the Sales Price on Project Approval.
– Check pricing logic against Use Bookable Resource specific pricing field’s value on Bookable Resource to prevent inconsistent Time Entries from being approved (for example can’t approve an entry that has Pricing logic in use = Role specific when Use Bookable Resource specific pricing = Yes).
– Alert the user if Sales Price doesn’t match the original Bookable Resource specific Sales Price copied from Bookable Resource or the original Role specific Sales Price.
– Hide Time Entry related custom fields when approving Expenses.
Project Approval provides a place to change the Sales Price as well as hold the original pricing information. The pricing logic can also be changed on Project Approval. As Journal Lines are created when a Time Entry is submitted and as the relevant price fields affecting Actuals are on Journal Lines, this step of customizing Project Approvals is not mandatory. This step does however make the entire Time Entry -> Journal Lines -> Project Approval -> Actuals process consistent data wise so I recommend to at least add a price field with a Bookable Resource specific price on the Project Approval Form.
A prerequisite to customizing Project Approval is making the Sales Price msdyn_salesprice visible on the form as well as setting the field Entry Type msdyn_entrytype on it. To set the Sales Price field visible, follow the instructions found in my earlier blog post Changing the Sales Price of a Time Entry at Project Approval.
1. Create a Two Option field for the pricing logic, a Sales Price field to which the original Sales Price (Role specific) will be copied to as well as a field to hold the Bookable Resource specific Sales Price from Bookable Resource at Time Entry creation. Add the previously created Quick View for Project Approval on the form. Set the OOTB Sales Amount field msdyn_salesamount on the form.
Fields on Project Approval
Project Approval form with new fields and Quick Create on it
2. This workflow sets the correct pricing logic on Project Approval when a record is created. Create a workflow (named Set Sales Price on Project Approval in this example) that copies the value from Sales Price msdyn_salesprice to Role based default Sales Price on Project Approval. The workflow also copies the value Bookable Resource specific Sales Price on Bookable Resource to Original Bookable Resource specific Sales Price. This field will hold the value that was on Bookable Resource at the time the Time Entry was submitted.
As a record is created, if Use Bookable Resource specific pricing is set to Yes on Bookable Resource then the value on Pricing logic in use on Project Approval is set to Bookable Resource specific and Bookable Resource specific Sales Price on Bookable Resource is copied to Sales Price msdyn_salesprice. Otherwise Pricing logic in use is set to Role specific.
This workflow should run in real-time so that the workflow updating Journal Lines in stage 3’s 2nd step works correctly.
3. Create a workflow (named Check pricing logic on Project Approval in this example) that runs when the value of the pricing logic field Pricing logic in use, created in this stage’s 1st step, changes. The workflow checks that there isn’t an inconsistency between a chosen pricing logic on Project Approval and the Use Bookable Resource specific pricing field’s value on Bookable Resource. If the values are inconsistent, an error is displayed.
In this example the pricing logic is always controlled primarily by what is set on Bookable Resource. For the sake of example I have created this as a separate real-time workflow.
Workflow Check pricing logic on Project Approval
Details of workflow Check pricing logic on Project Approval
4. Create a workflow (named Prevent Time Entry approval if pricing logic is incorrect in this example) that runs before the field Record Stage changes on Project Approval. This workflow prevents Time Entries with an inconsistent pricing logic from being approved before a correct pricing logic is set. The workflow affects both Time Entry approvals and rejections. In order for the workflow to work as intended, it must run before Record Stage‘s value changes. The workflow needs to be real-time so that “Before Record fields change” can be selected.
Workflow Prevent Time Entry approval if pricing logic is incorrect
Details of workflow Prevent Time Entry approval if pricing logic is incorrect
5. This Business Rule alerts the user if Sales Price doesn’t match the original Bookable Resource specific Sales Price copied from Bookable Resource or the original Role specific Sales Price. The Business Rule also hides Time Entry related custom fields when Expenses are being approved. The Scope of the Business Rule is set to All Forms.
Business Rule for Project Approval customizations
The Business Rule’s logic
Business Rule’s conditions
6. Set the field Role based default Sales Price and Bookable Resource specific Sales Price as read-only. This way a user doesn’t accidentally change the original prices.
Stage 3 – Customizations on Journal Lines
Goals of stage 3:
– Update Journal Lines of Unbilled Sales and Cost when a Journal Line record is created.
– Allow the user to override the workflow that updates Journal Lines when there is a need to manually create a Journal Line from a Journal’s context.
When a Time Entry is submitted an Unbilled Sales and Cost Journal Line is created. As a workflow updating Sales Price msdyn_salesprice on Project Approval doesn’t update the field Price msdyn_price on a Journal Line, the Journal Line record has to be updated on create using a workflow. The workflow pulls the value to the fields Price msdyn_price and Amount msdyn_amount from the custom field on Bookable Resource. The Amount is then multiplied by Quantity msdyn_quantity.
Some fields used in this stage may be set as read-only on the Journal Line main form. Adjust field-level behavior on a field’s properties so that the necessary fields are customizable.
1. Create a Two Option field on the Quick Create form of the Journal Line entity. As the Quick Create is used when a new Journal Line record is created from a Journal’s context, placing the field on the Quick Create is enough.
Two Option field on Journal Line’s Quick Create
2. Create a background workflow (named Set Sales and Cost Price on Journal Lines in this example) that updates Journal Line records when they are created. The workflow has to run in the background for it to properly function together with the workflow updating Project Approval (stage 2, step 2). The workflow runs when Use Bookable Resource specific pricing is set to Yes on Bookable Resource. The other conditions on the workflow check that the record being updated is not a reverse Journal Line entry which is created mainly when correcting Actuals (in a case of an incorrect Time Entry approval for example).
Workflow Set Sales and Cost Price on Journal Lines
Conditions for updating an Unbilled Sales Journal Line
Properties for updating an Unbilled Sales Journal Line
Conditions for updating a Cost Journal Line
Properties for updating a Cost Journal Line
Stage 4 – Testing the customizations
Our final step is to test all the customizations made in steges 1-3. The background workflow updating the Journal Lines may take a short while to update the records so don’t be alarmed if you don’t see the Price and Amount fields change right away.
I hope this blog post enables you to take more out of Dynamics 365 Project Service Automation and its pricing features. This article is about giving you ideas on how to use Bookable Resource specific pricing. Please feel free to develop these ideas further to meet your specific business requirements.
Part II of this article can be found here.
All my blog posts reflect my personal opinions and findings unless otherwise stated.