]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/python/oils/org.py
verifying existance of org tree before building union tree
[working/Evergreen.git] / Open-ILS / src / python / oils / org.py
1 import osrf.ses
2 import oils.event, oils.const
3
4 class OrgUtil(object):
5     ''' Collection of general purpose org_unit utility functions '''
6
7     _org_tree = None  
8     _org_types = None  
9     _flat_org_tree = {}
10
11     @staticmethod
12     def _verify_tree():
13         if not OrgUtil._org_tree:
14             OrgUtil.fetch_org_tree()
15
16     @staticmethod
17     def fetch_org_tree():
18         ''' Returns the whole org_unit tree '''
19
20         if OrgUtil._org_tree:
21             return OrgUtil._org_tree
22
23         tree = osrf.ses.ClientSession.atomic_request(
24             oils.const.OILS_APP_ACTOR,
25             'open-ils.actor.org_tree.retrieve')
26
27         oils.event.Event.parse_and_raise(tree)
28         OrgUtil._org_tree = tree
29         OrgUtil.flatten_org_tree(tree)
30         return tree
31
32     @staticmethod
33     def flatten_org_tree(node):
34         ''' Creates links from an ID-based hash to the org units in the org tree '''
35         if not node:
36             node = OrgUtil._org_tree
37         OrgUtil._flat_org_tree[node.id()] = node
38         for child in node.children():
39             OrgUtil.flatten_org_tree(child)
40
41     @staticmethod
42     def get_org_unit(org_id):
43         OrgUtil._verify_tree()
44         if isinstance(org_id, osrf.net_obj.NetworkObject):
45             return org_id
46         return OrgUtil._flat_org_tree[org_id]
47         
48
49     @staticmethod
50     def fetch_org_types():
51         ''' Returns the list of org_unit_type objects '''
52
53         if OrgUtil._org_types:
54             return OrgUtil._org_types
55
56         types = osrf.ses.ClientSession.atomic_request(
57             oils.const.OILS_APP_ACTOR, 'open-ils.actor.org_types.retrieve')
58
59         oils.event.Event.parse_and_raise(types)
60         OrgUtil._org_types = types
61         return types
62
63
64     @staticmethod
65     def get_org_type(org_unit):
66         ''' Given an org_unit, this returns the org_unit_type object it's linked to '''
67         types = OrgUtil.fetch_org_types()
68         return [t for t in types if t.id() == org_unit.ou_type()][0]
69
70
71     @staticmethod
72     def get_related_tree(org_unit):
73         ''' Returns a cloned tree of orgs including all ancestors and 
74             descendants of the provided org '''
75
76         OrgUtil._verify_tree()
77         org = org_unit = OrgUtil.get_org_unit(org_unit.id()).shallow_clone()
78         while org.parent_ou():
79             parent = org.parent_ou()
80             if not isinstance(parent, osrf.net_obj.NetworkObject):
81                 parent = OrgUtil._flat_org_tree[parent]
82             parent = parent.shallow_clone()
83             parent.children([org])
84             org = parent
85         root = org
86
87         def trim_org(node):
88             node = node.shallow_clone()
89             children = node.children()
90             if len(children) > 0:
91                 node.children([])
92                 for child in children:
93                     node.children().append(trim_org(child))
94             return node
95
96         trim_org(org_unit)
97         return root
98
99     @staticmethod
100     def get_union_tree(org_list):
101         ''' Returns the smallest org tree which encompases all of the orgs in org_list '''
102
103         OrgUtil._verify_tree()
104         if len(org_list) == 0:
105             return None
106         main_tree = OrgUtil.get_related_tree(OrgUtil.get_org_unit(org_list[0]))
107
108         if len(org_list) == 1:
109             return main_tree
110
111         for org in org_list[1:]:
112             node = OrgUtil.get_related_tree(OrgUtil.get_org_unit(org))
113             main_node = main_tree
114
115             while node.id() == main_node.id():
116                 child = node.children()[0]
117                 main_child_node = main_node.children()[0]
118                 child.parent_ou(node)
119                 main_child_node.parent_ou(main_node)
120                 node = child
121                 main_node = main_child_node
122
123             main_node.parent_ou().children().append(node)
124
125         return main_tree
126
127     @staticmethod
128     def get_related_list(org_unit):
129         ''' Returns a flat list of related org_units '''
130         OrgUtil._verify_tree()
131         tree = OrgUtil.get_related_tree(org_unit)
132         orglist = []
133         def flatten(node):
134             orglist.append(node)
135             for child in node.children():
136                 flatten(child)
137         flatten(tree)
138         return orglist
139
140     @staticmethod
141     def debug_tree(org_unit, indent=0):
142         ''' Simple function to print the tree of orgs provided '''
143         import sys
144         for i in range(indent):
145             sys.stdout.write('_')
146         print '%s id=%s depth=%s' % (org_unit.shortname(), str(org_unit.id()), str(OrgUtil.get_org_type(org_unit).depth()))
147         indent += 1
148         for child in org_unit.children():
149             OrgUtil.debug_tree(child, indent)
150         
151