| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf8 -*-
2 """GNUmed staff objects."""
3 #============================================================
4 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
5 __license__ = "GPL"
6
7 # std lib
8 import sys
9 import logging
10
11 # GNUmed
12 if __name__ == '__main__':
13 sys.path.insert(0, '../../')
14 from Gnumed.pycommon import gmBusinessDBObject
15 from Gnumed.pycommon import gmPG2
16 from Gnumed.pycommon import gmNull
17 from Gnumed.pycommon import gmBorg
18 from Gnumed.pycommon import gmLog2
19
20
21 _log = logging.getLogger('gm.staff')
22
23 _map_gm_role2pg_group = {
24 u'public access': 'gm-public',
25 u'non-clinical access': u'gm-staff',
26 u'full clinical access': u'gm-doctors'
27 }
28
29 #============================================================
30 _SQL_fetch_staff_fields = u'SELECT *, _(role) AS l10n_role FROM dem.v_staff WHERE %s'
31
33 _cmd_fetch_payload = _SQL_fetch_staff_fields % u"pk_staff = %s"
34 _cmds_store_payload = [
35 u"""UPDATE dem.staff SET
36 short_alias = %(short_alias)s,
37 comment = gm.nullify_empty_string(%(comment)s),
38 is_active = %(is_active)s,
39 db_user = %(db_user)s
40 WHERE
41 pk = %(pk_staff)s
42 AND
43 xmin = %(xmin_staff)s
44 RETURNING
45 xmin AS xmin_staff"""
46 ]
47 _updatable_fields = ['short_alias', 'comment', 'is_active', 'db_user']
48 #--------------------------------------------------------
50 # by default get staff corresponding to CURRENT_USER
51 if (aPK_obj is None) and (row is None):
52 #cmd = u"select *, _(role) AS l10n_role from dem.v_staff where "
53 cmd = _SQL_fetch_staff_fields % u"db_user = CURRENT_USER"
54 try:
55 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
56 except:
57 _log.exception('cannot instantiate staff instance')
58 gmLog2.log_stack_trace()
59 raise ValueError('cannot instantiate staff instance for database account CURRENT_USER')
60 if len(rows) == 0:
61 raise ValueError('no staff record for database account CURRENT_USER')
62 row = {
63 'pk_field': 'pk_staff',
64 'idx': idx,
65 'data': rows[0]
66 }
67 gmBusinessDBObject.cBusinessDBObject.__init__(self, row = row)
68 else:
69 gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj = aPK_obj, row = row)
70
71 # are we SELF ?
72 self.__is_current_user = (gmPG2.get_current_user() == self._payload[self._idx['db_user']])
73
74 self.__inbox = None
75 #--------------------------------------------------------
77 if attribute == 'db_user':
78 if self.__is_current_user:
79 _log.debug('will not modify database account association of CURRENT_USER staff member')
80 return
81 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
82 #--------------------------------------------------------
84 rows, idx = gmPG2.run_ro_queries (
85 queries = [{
86 'cmd': u'select i18n.get_curr_lang(%(usr)s)',
87 'args': {'usr': self._payload[self._idx['db_user']]}
88 }]
89 )
90 return rows[0][0]
91
93 if not gmPG2.set_user_language(language = language):
94 raise ValueError (
95 u'Cannot set database language to [%s] for user [%s].' % (language, self._payload[self._idx['db_user']])
96 )
97 return
98
99 database_language = property(_get_db_lang, _set_db_lang)
100 #--------------------------------------------------------
102 if self.__inbox is None:
103 from Gnumed.business import gmProviderInbox
104 self.__inbox = gmProviderInbox.cProviderInbox(provider_id = self._payload[self._idx['pk_staff']])
105 return self.__inbox
106
109
110 inbox = property(_get_inbox, _set_inbox)
111 #--------------------------------------------------------
113 from Gnumed.business import gmPerson
114 return gmPerson.cIdentity(aPK_obj = self._payload[self._idx['pk_identity']])
115
116 identity = property(_get_identity, lambda x:x)
117 #--------------------------------------------------------
119 if role.strip() == self._payload[self._idx['role']]:
120 return True
121
122 cmd = u'SELECT gm.add_user_to_permission_group(%(usr)s::name, %(grp)s::name)'
123 args = {
124 'usr': self._payload[self._idx['db_user']],
125 'grp': _map_gm_role2pg_group[role.strip()]
126 }
127 rows, idx = gmPG2.run_rw_queries (
128 link_obj = conn,
129 queries = [{'cmd': cmd, 'args': args}],
130 get_col_idx = False,
131 return_data = True,
132 end_tx = True
133 )
134 if not rows[0][0]:
135 return False
136 self.refetch_payload()
137 return True
138
139 role = property(lambda x:x, set_role)
140 #============================================================
142 if active_only:
143 cmd = _SQL_fetch_staff_fields % u'is_active ORDER BY can_login DESC, short_alias ASC'
144 else:
145 cmd = _SQL_fetch_staff_fields % u'TRUE ORDER BY can_login DESC, is_active DESC, short_alias ASC'
146 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
147 staff_list = []
148 for row in rows:
149 obj_row = {
150 'idx': idx,
151 'data': row,
152 'pk_field': 'pk_staff'
153 }
154 staff_list.append(cStaff(row=obj_row))
155 return staff_list
156 #------------------------------------------------------------
158 args = {
159 'pg_usr': db_account,
160 'pwd': password,
161 'person_id': identity,
162 'sig': short_alias
163 }
164
165 queries = [
166 {'cmd': u'SELECT gm.create_user(%(pg_usr)s, %(pwd)s)', 'args': args},
167 {'cmd': u"""
168 INSERT INTO dem.staff
169 (fk_identity, db_user, short_alias)
170 VALUES (
171 %(person_id)s,
172 %(pg_usr)s,
173 %(sig)s
174 )""",
175 'args': args
176 }
177 ]
178
179 try:
180 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
181 except gmPG2.dbapi.IntegrityError, e:
182 if e.pgcode == gmPG2.sql_error_codes.UNIQUE_VIOLATION:
183 msg = _(
184 'Cannot add GNUmed user.\n'
185 '\n'
186 'The database account [%s] is already listed as a\n'
187 'GNUmed user. There can only be one GNUmed user\n'
188 'for each database account.\n'
189 ) % db_account
190 return False, msg
191 raise
192
193 return True, None
194 #------------------------------------------------------------
196 queries = [{'cmd': u'DELETE FROM dem.staff WHERE pk = %(pk)s', 'args': {'pk': pk_staff}}]
197 try:
198 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
199 except gmPG2.dbapi.IntegrityError, e:
200 if e.pgcode == gmPG2.sql_error_codes.FOREIGN_KEY_VIOLATION: # 23503 foreign_key_violation
201 msg = _(
202 'Cannot delete GNUmed staff member because the\n'
203 'database still contains data linked to it.\n'
204 '\n'
205 'The account was deactivated instead.'
206 )
207 deactivate_staff(conn = conn, pk_staff = pk_staff)
208 return False, msg
209 raise
210
211 return True, None
212 #------------------------------------------------------------
214 # 1) activate staff entry
215 staff = cStaff(aPK_obj = pk_staff)
216 staff['is_active'] = True
217 staff.save_payload(conn=conn) # FIXME: error handling
218
219 # 2) enable database account login
220 rowx, idx = gmPG2.run_rw_queries (
221 link_obj = conn,
222 # password does not matter because PG account must already exist
223 queries = [{'cmd': u'select gm.create_user(%s, %s)', 'args': [staff['db_user'], 'flying wombat']}],
224 end_tx = True
225 )
226
227 return True
228 #------------------------------------------------------------
230
231 # 1) inactivate staff entry
232 staff = cStaff(aPK_obj = pk_staff)
233 staff['is_active'] = False
234 staff.save_payload(conn = conn) # FIXME: error handling
235
236 # 2) disable database account login
237 rows, idx = gmPG2.run_rw_queries (
238 link_obj = conn,
239 queries = [{'cmd': u'select gm.disable_user(%s)', 'args': [staff['db_user']]}],
240 end_tx = True
241 )
242
243 return True
244 #============================================================
247 #============================================================
249 """Staff member Borg to hold currently logged on provider.
250
251 There may be many instances of this but they all share state.
252 """
254 """Change or get currently logged on provider.
255
256 provider:
257 * None: get copy of current instance
258 * cStaff instance: change logged on provider (role)
259 """
260 # make sure we do have a provider pointer
261 try:
262 self.provider
263 except AttributeError:
264 self.provider = gmNull.cNull()
265
266 # user wants copy of currently logged on provider
267 if provider is None:
268 return None
269
270 # must be cStaff instance, then
271 if not isinstance(provider, cStaff):
272 raise ValueError, 'cannot set logged on provider to [%s], must be either None or cStaff instance' % str(provider)
273
274 # same ID, no change needed
275 if self.provider['pk_staff'] == provider['pk_staff']:
276 return None
277
278 # first invocation
279 if isinstance(self.provider, gmNull.cNull):
280 self.provider = provider
281 return None
282
283 # user wants different provider
284 raise ValueError, 'provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff'])
285
286 #--------------------------------------------------------
289 #--------------------------------------------------------
290 # __getitem__ handling
291 #--------------------------------------------------------
293 """Return any attribute if known how to retrieve it by proxy.
294 """
295 return self.provider[aVar]
296 #--------------------------------------------------------
297 # __s/getattr__ handling
298 #--------------------------------------------------------
304 # raise AttributeError
305 #============================================================
306 # main/testing
307 #============================================================
308 if __name__ == '__main__':
309
310 if len(sys.argv) == 1:
311 sys.exit()
312
313 if sys.argv[1] != 'test':
314 sys.exit()
315
316 import datetime
317 from Gnumed.pycommon import gmI18N
318 from Gnumed.pycommon import gmDateTime
319
320 gmI18N.activate_locale()
321 gmI18N.install_domain()
322 gmDateTime.init()
323
324 #--------------------------------------------------------
330 #--------------------------------------------------------
332 staff = cStaff()
333 provider = gmCurrentProvider(provider = staff)
334 print provider
335 print provider.inbox
336 print provider.inbox.messages
337 print provider.database_language
338 tmp = provider.database_language
339 provider.database_language = None
340 print provider.database_language
341 provider.database_language = tmp
342 print provider.database_language
343 #--------------------------------------------------------
344 test_staff()
345 #test_current_provider()
346
347 #============================================================
348
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Oct 5 03:57:14 2013 | http://epydoc.sourceforge.net |