EPM GROOVY – Setting Up Read-Only Planning Forms with Global Forms

This sounds more like controlling a specific product or entity read only from the planning unit hierarchy. This post is for those who don’t use planning unit hierarchy but use a webform to control whether planners are supposed to edit a certain product or entity during the planning cycle. Below is how groovy can help to lock the planning forms based on an assumption form.

Assumption Form:

It is a global form that would be controlled by super users to determine whether a certain product is allowed for input or not.

Sample Global form:

We shall read the status of the product from the planning form, then read the status and make the form cells read only based on the status. I have cola and diet cola products that are inactive, so the products are not supposed to be input in the planning form.

Run before Load Rule on planning forms:

Step 1: Create assumption form using GridDefinitionBuilder

Get cube and product details from the header cell.

Cube cube = operation.cube
def product = operation.grid.pov.find{DataGrid.HeaderCell it -> it.dimName == 'Products'}.collect{DataGrid.HeaderCell it -> it.MbrName} 

create and load assumptions intersection grid definition builder

DataGridDefinitionBuilder refBuilder = cube.dataGridDefinitionBuilder() 
def povDimensions = ['custom1','Channel','Years','Scenarios','Versions','custom2','Periods']
def povMembers = [['custom1'],['No Channel'],['&PlanYear'],['Budget'],['Working'],['Custom2'],['BegBalance']]
def columnDimensions = ['Metrics']
def columnMembers = [ ['Product Status'] ]
def rowDimensions = ['Products']
def rowMembers = [product]

//build the grid
refBuilder.addPov(povDimensions, povMembers)
refBuilder.addColumn(columnDimensions, columnMembers)
refBuilder.addRow(rowDimensions, rowMembers)   
DataGridDefinition gridDefinition = refBuilder.build()
Step 2: Access the Status of the products

The Groovy API provides a Cell class to access the String value using getFormattedValue(). This is different from the DataCell class.

def status 

cube.loadGrid(gridDefinition, false).withCloseable { globalGrid ->
	globalGrid.dataCellIterator.each {Cell cell ->    	
    	status = cell.getFormattedValue()
Step 3: Make planning cells read only based on the product Status
if (status == 'Inactive') {
	operation.grid.dataCellIterator.each {
    	it.forceReadOnly = true

The rule needs to be added as ‘Run After Load’.

Finally, Execution

From the global assumption form, “cola” is inactive and “caffeine-free cola” is active.