Answered

Have a reusable form obtain xpath data from the process level context

I have a reusable (sub form) in a process form. In the process table, I have a data value I want to use within the sub form. However, the sub form only has as context it's own entity.

Is there a way a sub form, whose only context is the entity in which it lives it, to communicate to the App context, and get data there?

I tried doing Business Rules, (the app name), Vocabulary, Xpath definitions, with a "get" and a "set".

However I haven't found how to use those within an expression. The online help has no examples.

Below, an over-simplification of what I am trying to accomplish.

An example of what I am trying to do. In application "Orchard" I have a process called Pick A Tree. I also have an entity called M_Warehouse (+ parameter P_WarehouseLocation) with a collection of entity M_TreeInventory (with many records of trees and their type) and a parameter called P_TreeType (1=Fruit tree, 2=Decorative tree).

In the process Pick A Tree, a user is prompted to select a warehouse, then a tree type, and is shown a read-only collection based on the two choices made. The choices are stored in the process table, the collection grid is a reusable form in the entity M_Warehouse and shown in the second form.

Form 1 (process form) - use selects a warehouse (search control), then a tree type (parameter lookup).

- xpaths are: PickATree.eWarehouse and PickATree.eTreeType

Form 2 (process fom) - we display the two choices on the form at the top (non editable) and below we attach the reusable form frmShowWarehouseTrees, so we have a sub form.

frmShowWarehouseTrees - has the M_Warehouse.sName attribute (non editable) and a (non editable) collection from M_TreeInventory. xpaths are:

- M_Warehouse.sName string 50

- M_Warehouse.cTreeInventory collection of M_TreeInventory

- M_TreeInventory.eTreeType relation to parameter P_TreeType

I create a filter expression script on the collection within frmShowWarehouseTrees, if I hardcode a specific value, say of 1 to only show fruit trees:

var sFilter = "eTreeType = 1";

sFilter;

Now I want to make it dynamic. The value that I want to use is in xpath PickATree.eTreeType.Id, but the reusable form - filter expression has a context of M_Warehouse, so cannot "see" that xpath.

Ways I have thought of doing this are:

Using way too much engineering:

- a special master table M_GlobalVariable with a record per user, with attributes sTemp1, iTemp1, dTemp1 and 2,3,4...

- two global library rules or expressions (a setter and a getter per attribute, that takes the current username as an input parameter

- the getter does a GetEntity lookup into that "special" table M_GlobalVariable, and the setter does a SetAttrib. I have to make sure all records exist for every WFUSER or the getter will fail.

Using xpath definitions

- I haven't found any examples at how to do this

Using an "extra" attribute in the M_Warehouse entity:

- M_Warehouse.iIdTreeTypeLookup (int)

- The process form fills it in, using expression:

PickATree.eWarehouse.iIdTreeTypeLookup = PickATree.eTreeType.Id;

- Then in the reusable form, the filter expression would be:

// Look in the warehouse entity for a preset filter to use, else, show all records

var sFilter = null;

var iIdTreeTypeVar = M_Warehouse.iIdTreeTypeLookup; // TreeInventory is a collection within M_Warehouse

if (iIdTreeType == null) {

sFilter = "eTreeType is not null"; // Show all trees with a defined type

}

else {

sFilter = "eTreeType = " + iIdTreeTypeVar; // Show trees for a specific type

}

sFilter;

*** Last method is probably the simplest, however, I don't like making extra fields in the parent entities just for this type of scenario. It is storing useless information.

Please help!

Comments (3)

photo
1

So far, I have done this (that works well)

I have a M_ApplicationVariable entity, that stores sProcessName, iCaseId, sUsername, sVar1

Using Business Rules, Library Rules, I have a GetSet function script that reads / writes into this table.

The first parameter is "Me" from which I get sProcessName, iCaseId, sUsername.

The second parameter, the actual value. If null, it does a "Get". If not null, it does a "Set"

Get = GetEntity (filtering with sProcessName, iCaseId, sUsername)

Set = does a Get, then changes the value for sVar1, then does a .Update() on the GetEntity object

What I didn't know, starting into this, was that the object you create with GenEntity, that object you can change the data values, and write back to the database with ObjectName.Update().

This wiki entry helped: http://wiki.bizagi.com/en/index.php?title=Other_Rules#How_to_Modify_Information_in_the_Entries_of_an_Entity

This method proves that Bizagi could give us a built-in mechanism for reading / writing global variables with the context that we want (using Me). I just need it within a process, so I store in that M_ApplicationVariable entity the values:

sProcessName = Me.Case.ProcessDefinition.Name

iCaseId = Me.Case.Id

sUsername = Me.Case.WorkingCredential.UserName

"Name" of the variable, and the "Value" of the variable - the type needs to be set in advance, and match the return type.

Thanks to the ability of creating library rule functions, this is possible.

Note that function parameter list is hardcoded (name & type) and the return is also hardcoded (type), you need a GetSet function for each type, should you want more than "String".

I haven't bothered with sending an object and retrieving an object, as that would make the code that calls this "function" much more complex. This isn't C# with classes...

photo
1

Dear Mark,

It sounds great! We are glad that you have found out the solution to this issue.

Regards

photo
1

John last year asked about something similar.

http://feedback.bizagi.com/suite/en/topic/is-it-possible-to-use-temporary-attributes-in-reusable-forms

This issue is a big thing for new Bizagi users. Attributes set in the process table, within a process, are unavailable in a reusable form.

Unless - you "create" these additional attributes in your entity table, so that they exist in an XPath within the process, because the process table is "linked" to your entity table.

So some logic in the process can "set" a value using <YourProcessEntity.eYourLinkedEntity.sSomeAttribute> = "hello" and then in your reusable form, having context "YourLinkedEntity", you can look at <sSomeAttribute>.

This pollutes the entity with attributes you don't care about, once your process is done.

So either a complicated work-around like I did (see above) using a Library Rule function & CEntityManager to read & write in an "out-of-context" manner, or. . .

Don't use reusable forms ! (unless you understand the work-around)

Which makes zero sense... One thing we do is make reusable "parts" and assemble the "parts" in the process form, like standard headers & footers.

Like this we don't have to redesign everything across multiple processes that use the same entities over & over.

(solution for Bizagi devs)

If only there was a way to access the through the Me object...all we can get now is the process name.