Thoughts, ideas and solutions from a few EPM consultants.

Creating DRM Properties that Inherit from Descendants

Overview

To inherit is defined as "to receive or be left with (a situation, object, etc.) from a predecessor or former owner." DRM allows for property inheritance which works great for things like Account Types in planning applications or currencies on entities but, what happens when you need to go the other way? What happens if you want parents to be included in an export if level zero members are without having to set a property on every intermediate member. Out of the box DRM doesn't support reverse inheritance.

Secenario

For this example I will demonstrate the use of reverse inheritance to include parents in a export when children are enabled. This was a requirement for my current project although we took it a few steps further allowing intermediate levels to be skipped as well.

How

To accomplish this task I created two properties TEV.IsMember and TEV.IsMemberLeaf. In addition to the properties I implemented some node types to determine when each of these properties is visible so that the leaf property is only available at the lowest level.

IsMemberLeaf

This property at its core is a local, boolean value. I have added additional logic to default this property to certain values depending on what hierarchy its being used in but, that's a different topic.

IsMember

IsMember is a local, boolean, derived property that uses JavaScript to determine its value. The breakdown of the logic here is as follows. First, I check to see if the member is either a shared node or member with no children (In your implementation you may be able to rely on the leaf property but the environment I am working with I could not.) Next, I use the DescendantsWith function, which documentation says is the fastest way to traverse the hierarchy, to find a level zero member with TEV.IsMemberLeaf enabled. The 1 next to the true means that the function should stop when it returns the first result that meets the requirements. Since this function returns an array of objects (one in our case) if something is found and null if not we don't need to know the value of what was returned only that a value was returned. Therefore the test is that the returned value is not null.

if (node.PropValue("Core.SharedFlag_MDM") || node.PropValue("Core.Children") == 0)
    return node.PropValue("TEV.IsMemberLeaf");
else 
    return node.DescendantsWith(function (x){ 
        return x.PropValue("TEV.IsMemberLeaf") == true &&
              (x.PropValue("Core.Children") == 0 ||
               x.PropValue("Core.SharedFlag_MDM"));
        }, 1, true) != null;

Usage

When creating a export we can now add TEV.IsMember equals true as a requirement for being included in the export.

Other Options

If you happen to be using reverse inheritance for export purposes it may be best to take a look at Is Above. This query option allows DRM to look at children of a member and determine if a condition is satisfied. Using this means that the IsMember not terribly useful from an export point of view but it is helpful in that users know what is going to being included in the export.