Developing Project Essential 2012 Applications – Working with Cost Center Values

Code Samples, Project Essentials, SDK

The current article is a follow up to the previous one, detailing how to read and update budget values for a project. We will show how to work with cost center values.

Cost Centers are elements which help enterprises track and control cost more efficiently, generally a segment of a business or other organization in which costs can be segregated. Each department for example could be a cost center. You globally define cost centers, you can group them in various combinations and similar to cost nodes in cost templates, you can select just a subset of cost centers and associate them to Enterprise Project Types and Projects.

In Project Essentials 2010, the concept of Cost Centers applies only to Budget, starting with Project Essentials 2012 cost centers can be defined for each Enterprise Financial Type and Financial Dimensions.

From an API point-of-view to determine which Cost Center Template is assigned to a project, you must refer the entity settings of the financial project instance (the data row in the FinancialTypesInfo.cmEntitySettings table corresponding to your project). You can only have a Cost Center Template associated to a project if that project has a Cost Tree Template association.

The Entity Settings row has a property called CostCenterTemplateGUID, that indicates the template. For instances that have no template assigned, the CostCenterTemplateGUIDNull() method will evaluate to true.

To find out all the information about a template, you use the ReadCostCentersTemplate(Guid templateUid, bool includeStructure) method of the CostCenters service:

  •  templateUid – the identifier of the cost tree template
  •  includeStructure – if set to true, the returned dataset will also include details about the cost centers in the CostCentersInfo.cmCostCenters data table (the name and the description), in the CostCentersInfo.cmCostCenterTemplateNodeLinks data table (default cost centers – the ones that are set as visible in the webpart) and in CostCentersInfo.cmCostCenterGroups (cost center groups), otherwise only the list of cost centers identifiers is available in the CostCentersInfo.cmCostCenterTemplates data table.

Project Essentials stores financial values for each granular time period, per cost node and cost center.

To read financial values, the ReadFinancialValues method from the FinancialValues service should be used. It has a parameter called costCenters(a Guid array):

  • if you specify null, you will get all the values, for all the cost centers
  • if you pass an array with Guid.Empty as the only element, you will get the values aggregated for each cost node (the cost center breakdown is ignored, all the cost center values for a node are summed up to get the total node value)
  • if you specify unique identifiers that correspond to just a subset of the cost centers included in the template, the returned dataset will contain the filtered values for only those centers

The costCenters parameter, allows you to mimic with the API the behavior that you get when you use the Cost Centers filter in the financial web parts.


In the financial web parts, for each node, besides the cost centers from the template that you select in the filter, you get two additional rows:

  • Total – this is the sum of all cost centers values; it is read-only and you cannot edit the value
  • Unallocated – this is computed as the difference between the Total value and the sum of all cost center values


In Project Essentials 2012 the Unallocated cost center can be hided from the Cost Center Filter page, by unchecking the “Unallocated” cost center from the list of available ones, just like you do for other cost centers.


In the dataset returned by the ReadFinancialValues method, there is no row that corresponds to the Total node value. You will have to roll out your own logic to compute the value, but it is fairly easy:

decimal total = valuesDs.cmFinancialValues.Where(financialValue => financialValue.NodeGUID == nodeUid).Sum(financialValue => financialValue.Value);

In the default usage scenario, the business logic of Project Essentials does not allow you to add values to the Unallocated cost center, this node is read-only in the financial web parts. However, if you add values to the project before associating a cost center template, when you do assign a template, the existing values will end up in the Unallocated center. When you add a value on a cost center for a cost node, the value is subtracted from the Unallocated value, and will not increase the Total value if it is smaller than the unallocated amount; if it is greater, the Unallocated value will be zeroed out.

To exemplify this, let us consider the situation of the Expenses node, having an Unallocated value of 10,000$, and two cost centers Fin1 and HR2:


In the response dataset, when you read the values through the API, the rows corresponding to the Unallocated virtual cost center are identified by having Guid.Empty (00000000-0000-0000-0000-000000000000) in the CostCenterGUID column. It is up to you to manage these rows and update their values appropriately when modifying rows for the other cost center value, if you wish to get the same results you would by manually editing values in the web parts.

The sample application provided with the previous article has been updated to also include functionality for cost centers.


Code Samples

What do you think?