I've now implemented the PE hierarchy framework I was talking about the other
day, and hopefully it will make its way into trunk sooner or later.
The basic idea is that person entities can be affiliated with other person
entities with a certain role. Person entities means all types which implement
the pr_pentity link, i.e. organisations, offices, groups, persons.
So, if for example a person is a member of an organisation, then this can be
expressed as:
Organisation X <-- Members <--> Person A
The same structure can be used to express that a person is a member of a team:
Team Y <-- Members <--> Person A
The "Members" here is a role, and there can be many different affiliation
roles, e.g.:
Organisation X <-- Regional Branches <--> Organisation XY
Each "role" can of course have multiple members:
Organisation X <-- Regional Branches <--> [Organisation XY, Organisation XZ]
The member types can be mixed:
Team Y <-- Units <--> [Person A, Person B, Team C]
Some of these "roles" can define a hierarchy (in the sense of "reporting sub-
units") - others won't. This can be expressed by a "role type", where the
current implementation only recognizes one particular role type as hierarchy
type (i.e. currently there is only one hierarchy possible):
Team Y <-- Units (Type: OU) <--> [Person A, Person B, Team C]
Team C <-- Team Members (Type: OU) <--> [Person D, Person E]
As simple as that sounds, it's exactly what this framework implements. Besides
the model, I've also implemented a couple of back-end methods to support it,
e.g. (playable at the CLI):
# Take an organisation (by its pe_id):
>>> s3db.pr_pentity_represent(4)
'Example.edu (Organization)'
# Create a role "Units" (type: OU) for Example.edu:
>>> s3db.pr_define_role(4, "Units", role_type=1)
20
# Take another organisation:
>>> s3db.pr_pentity_represent(5)
'Example.com (Organization)'
# Add this organisation to the "Units" role we created before:
>>> s3db.pr_add_to_role(20, 5)
# Define a role "Staff" for Example.com
>>> s3db.pr_define_role(5, "Staff", role_type=1)
21
# Take a person (by its pe_id):
>>> s3db.pr_pentity_represent(144)
'Eve Hays [No ID Tag] (Person)'
# Add this person to the "Staff" role of Example.com
>>> s3db.pr_add_to_role(21, 144)
# Find all ancestor PE's of Eve:
>>> s3db.pr_get_ancestors(144)
['5', '4']
# Find all descendant PE's of Example.edu
>>> s3db.pr_get_descendants(4)
[5, 144]
# Get all ancestor paths for "Eve":
>>> s3db.pr_get_path(144).as_list()
[['5', '4']]
# Add "Eve" to the "Units" role of example.edu directly:
>>> s3db.pr_add_to_role(20, 144)
# Check all ancestors paths for "Eve" again:
>>> s3db.pr_get_path(144).as_list()
[['5', '4'], ['4']]
..."Eve" does now have two ancestor paths, one directly to example.edu, and
one via example.com as a sub-unit of example.edu.
This toolkit supports any number of ancestor paths, i.e. the same person
entity can be linked to multiple ancestors, and except for the direction of
each vertex in a path, no particular hierarchy is required. Paths can go up or
down or criss-cross - doesn't matter (loops are auto-resolved).
Additionally, I've added a toolkit for manipulating paths with multiple
ancestors - S3MultiPath. Internally, it is used to manage ancestor lookup
paths, but it can also be used to work with the paths returned by get_path,
e.g.:
# Get the path
>>> path = s3db.pr_get_path(144)
>>> path.as_list()
[['5', '4'], ['4']]
>>> 5 in path
True
>>> [5,4] in path
True
>>> [5,3] in path
False
# Use & to check whether the sequence is a direct ancestor path
>>> path & 4
1
# Remove the direct affiliation of "Eve" with example.edu:
>>> s3db.pr_remove_from_role(20,144)
>>> path = s3db.pr_get_path(144)
>>> path.as_list()
[['5', '4']]
# Now example.edu is no longer a direct ancestor of "Eve"
>>> path & 4
0
...and other methods.
The question is what to do with this now - users won't usually work at the
CLI.
Our current PE "hierarchy" is spread out across multiple tables and linkage
variants, e.g. group_membership, hrm_human_resource or
org_site.organisation_id - and more. These constructs should either auto-
create/remove role affiliations, or be replaced by them.
Additionally, we certainly want to have a set of "default roles" auto-created
per each PE type, as well as a way to pre-populate them.
As a UI option for the management of the PE hierarchy, a tree view/widget has
been suggested. This would show the descendant tree under a PE in a file-
system-alike manner, where the "roles" are folders and the "affiliates" the
files inside them.
Later we may want to support multiple hierarchies, which would need a minor
extension of this framework - and a huge amount of UI work to have this any
understandable/manageable for the user.
Another issue could be to let the user select flexible cascades and
combinations of affiliation-dependent configuration settings, e.g. map
settings and overlays. A really flexible UI for that could though become
extremely complex and scary - so it needs to be either limited or
collapsible/expandable in its flexibility.
Any help welcome (as well as discussion, although I'm limited there due to
time constraints).
Dominic
http://eden.sahanafoundation.org/wiki/BluePrintPersonEntityModel
(BluePrints may not be the right place, but where else?)
Dominic
DeveloperGuidelines?
- that's better for 'is' rather than 'might be', no?
F
Regards,
Benjamin
_________________
Sent from an iPad2. Please excuse typos.
The framework? Right now.
A complete UI including authorization could take 2-4 more weeks.
Dominic