Project budget management in Project Operations

Project Operations Lite version 4.59.0.210

Project budget management, or project budgeting as it’s referred to in the 2022 wave 2 release plan, is a capability that allows project managers to keep track of spend against a defined project budget. A budget is a point-in-time snapshot of the estimated spend across a project and its tasks. Learn defines a project budget as:

“A project budget represents a point-in-time snapshot of the estimated spend across the project phases and its associated tasks. Even if the prices of the resources, materials, or expenses change, the changes don’t affect the budget snapshot after it’s made part of the budget.”

Project budget management was released for the Lite deployment in version 4.59.0.210 around February 2023. The feature contains the initial capabilities for managing project budgets, with future releases in 2023 containing additional capabilities such as project budget revisions and on-demand refresh of the project budget grid.

Project budget management

Let’s run through the basics of creating and approving project budgets in Dynamics 365 Project Operations. Learn has a good article on the end-to-end process of managing budgets if you’re interested in the project budgeting process flow. This post will focus on how a budget is created and what some of the gotchas in project budget management are.

The project budget management feature is behind a feature flag that must be enabled under Parameters. The feature enablement follows the same logic as other new ProjOps features, such as modern approvals. After the feature is turned on, it’s ready to be used as it is with OOTB settings for budget line match priority.

Budget line match priority

The one setting you might need to change depending on your use cases for project budgets is the budget line match priority. As Learn states, “budget line match priority defines the order in which an actual is matched against the different dimensions of budget lines.” Priorities can be edited, deleted, and created. It’s worth a mention that at the time of writing this post, all managed properties for the Project Budget Match Priority table are set to no customizations allowed, so we have to use what the Product Group gives us. I’ve solved sorting the match priority grid by enabling an editable grid on the Project Parameter main form and using grouping in the editable grid.

Image 1. Edited budget match priorities with editable grid enabled.

Understanding how the match priory works may take some trial and error so play around with the project budget management feature in your sandbox to understand how it works. Before we look at the matching priority more closely, we must define terminology. The concept behind matching is based on dimensions on actuals and project budget lines. Dimensions include role, organizational unit, bookable resource, project task, etc.

When a cost actual is created, its dimensions are matched with the dimensions of all budget lines in a project budget. The budget line match priority defines the order in which the matching algorithm works with priority 1 being the highest priority. A match between an actual and a budget line is made when a budget line matches most of the actual’s dimensions.

If the algorithm doesn’t find a match and doesn’t run into an error, it avoids the dimension with the lowest priority (the highest priority number in the transaction class in question), and a new attempt to match an actual with a budget line is made.

Matching example

Let’s look at an example. Table 1 below illustrates dimensions with populated values on a cost actual and a budget line.

Display NameLogical Name
Rolemsdyn_resourcecategory
Organizational Unitmsdyn_resourceorganizationalunitid
Bookable Resourcemsdyn_bookableresource
Table 1. Example dimensions.

Now that we’ve established the dimensions that are populated on an actual and a budget line, let’s look at an example of the matching priorities, and then see how matching works. For the sake of simplicity, let’s consider a scenario where the matching priority is OOTB. Table 2 illustrates the OOTB matching priority for the transaction class of Time.

Display NameLogical NameTransaction ClassContextPriority
Rolemsdyn_resourcecategoryTimeCost1
Organizational Unitmsdyn_resourceorganizationalunitidTimeCost2
Bookable Resourcemsdyn_bookableresourceTimeCost3
Project Taskmsdyn_taskTimeCost4
Cost Typemsdyn_costtypeTimeCost5
Vendormsdyn_accountvendorTimeCost6
Table 2. Example matching priorities.

Next, let’s look closer at matching. If no match is found for all six dimensions in table two, and no error is encountered, the matching algorithm avoids the lowest-priority dimension, and tries to match again. This process continues until a match is found or an error is encountered. If more than one budget line matches an actual, this situation is considered an error. In this example, the algorithm would find a match after it has avoided priorities six to four. Since dimensions for priorities three, two, and one are populated on an actual and a budget line, a match is found.

Let’s explore this scenario further from a slightly different angle. Let’s say that we have a project budget line with only Task set on it as a dimension. Image 2 below illustrates this scenario. In this case, an actual will not be matched with a project budget line if the matching priority follows table two. Why is this? The answer is in what’s in the matching priority table and what’s on a project budget line: The matching is looking for role, org unit, bookable resource, and then project task, but the project budget line only has a dimension for project task. Since none of priorities 1-3 are found, and the matching avoids priorities starting from six, a match is never found. In other words, since none of the columns from priorities 1-3 are set as dimensions on the project budget line, no match is found. If the priority of Project Task was set to one, a match would be found since that dimension is present on the actual and the project budget line, and it’s the highest priority being evaluated.

Image 2. Task as the only dimension on a project budget line.

Creating a project budget

Let’s start by creating a very simple project plan with two tasks. After the plan is created, a new project budget can be created from the command bar. When writing this blog post in February 2023, adding a project budget from estimates was still in development.

Image 3. Creating a project plan and a budget.

When a project budget has been created, a project budget line can be added from the budget’s subgrid. Learn describes all the options available when creating a budget line so I won’t describe the differences in this post. There are a couple of very important gotchas in this, though!

  • Price and Amount can be populated based on a cost price list. You have to be aware of how your cost price list has been set to make sure you get the expected results.
  • You must know the budget match priorities when creating a project budget line to get the expected results.

Based on the aforementioned points, consider what dimensions a project budget line should have so that cost actuals and the budget line match based on match priorities. In this example, I want to create one budget line that tracks the following:

  • Project Task Evaluate and document
  • Organizational Unit USA
  • Role Project Manager
  • The budget is created for an effort of 24 h

I also want to create another budget line that tracks the following:

  • Project Task Build and release
  • Organizational Unit USA
  • Role Project Manager or Consultant
  • The budget is created for a total cost of USD 5600 with a contingency of USD 400

Before we look at how the project budget lines are created, let’s see how my cost price list is set. The price list looks good, and it has: Roles for project manager and consultant, the resourcing unit is USA, and the price per hour is USD 100.

Image 4. Cost price list.

Now it’s time to look at the budget match priorities. Project Task, Organizational Unit, and Role are priorities 1-3. These look good for our example. It’s important to remember that the match priorities are defined on an organizational level! A PM can’t go in and change priorities without impacting the behavior of their peers’ project budget lines on other projects.

Image 5. Edited budget match priorities.

Next, it’s time to create the first budget line for project task Evaluate and document. The budget line is added from the Power Apps grid control’s command bar.

Image 6. Creating the first project budget line.

Now that the first budget line has been created, it’s time to create the second budget line. This one is role agnostic and is based on a total budget of USD 5600 and a contingency of USD 400.

Image 7. Creating the second project budget line.

Now that the budget has been created, it can be submitted from the command bar. After a budget has been submitted, it needs to be approved. This is also done from the command bar of a project row. Note that ProjOps doesn’t have any OOTB budget approvals built into it. You need to customize the system if you need one.

After a budget has been approved, it can’t be edited. Budget revisions are still in development as of February 2023, so you must make due before they’re GA. Deleting a budget isn’t possible either due to dependencies. If you look at the budget lines closely, you’ll notice that I’ve accidentally created the dates on the lines to overlap and I’d need to revise the budget. Unfortunately, I can’t as the budget has been approved and revisions aren’t yet in the product.

Image 8. Submitting a project budget.

Consuming a project budget

Let’s submit and approve time entries to consume the budget that’s been created. On Feb 8th I only worked 4 h so I should be well under budget for the Evaluate and document task. Image 9 below illustrates approvals for my time entries.

Image 9. Approving time to consume project budget.

As time entries are approved, cost actuals are created. Looking at one of the actuals, we can see that the command bar has a new button: Re-evaluate Budget association. The button triggers a re-evaluation process to match the actual with budget lines. They will appear behind the Budget Associations tab (image 11) when the association is made. The evaluation status in image 10 says Scheduled. This means that the actual is waiting for the recurring cloud flow Project Service – Recurrently Schedule Project Budget Evaluation to run. The flow runs on a recurrence of 5 minutes, but it can also be run manually if you’re impatient like me.

Image 10. Cost actual.
Image 11. Associated budget lines on an actual.

As the flow has run, we can look at all the actuals related to the time entries that were approved. The Budget Evaluation Status of all actuals is Complete, which means they will consume the project budget as intended.

Image 12. Actuals with Budget Evaluation Status set to Completed.

Looking at the project budget from a project’s context, we can see that the cost actuals have consumed the budget as intended. The 4 h that was logged for Feb 8th means budget line 1 for task Evaluate and document is under budget. The 2nd budget line’s consumption is at 40 % as the end date isn’t until Feb 17th. We can expect additional cost actuals created due to approved time entries to consume the budget for that line.

Image 13. Consumed budget based on approved time entries.

It’s worth mentioning that the Power Apps grid that displays budget lines doesn’t update in real-time. When opening a budget line, we can see that the columns for Actual Amount, Actual Quantity, and Actual Average Unit Cost are rollup columns. If you want to see immediate results, you have to open your project budget lines and refresh the rollups. This logic will hopefully see improvements in a later version of the feature so that results can be viewed in the grid in real-time.

Image 14. Rollup columns on a project budget line.

That’s all for now on project budget management! Let’s see what revisions bring in a future update. Be sure to leave a comment on your findings if you’ve tried creating project budgets.

All my blog posts reflect my personal opinions and findings unless otherwise stated.