| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
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 'public access': 'gm-public',
25 'non-clinical access': 'gm-staff',
26 'full clinical access': 'gm-doctors'
27 }
28
29 #============================================================
30 _SQL_get_staff_fields = 'SELECT *, _(role) AS l10n_role FROM dem.v_staff WHERE %s'
31
33 _cmd_fetch_payload = _SQL_get_staff_fields % "pk_staff = %s"
34 _cmds_store_payload = [
35 """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
49 #--------------------------------------------------------
51 # by default get staff corresponding to CURRENT_USER
52 if (aPK_obj is None) and (row is None):
53 cmd = _SQL_get_staff_fields % "db_user = CURRENT_USER"
54 try:
55 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
56 except Exception:
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
76 #--------------------------------------------------------
78 if attribute == 'db_user':
79 if self.__is_current_user:
80 _log.debug('will not modify database account association of CURRENT_USER staff member')
81 return
82 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
83
84 #--------------------------------------------------------
86 rows, idx = gmPG2.run_ro_queries (
87 queries = [{
88 'cmd': 'select i18n.get_curr_lang(%(usr)s)',
89 'args': {'usr': self._payload[self._idx['db_user']]}
90 }]
91 )
92 return rows[0][0]
93
95 if not gmPG2.set_user_language(language = language):
96 raise ValueError (
97 'Cannot set database language to [%s] for user [%s].' % (language, self._payload[self._idx['db_user']])
98 )
99 return
100
101 database_language = property(_get_db_lang, _set_db_lang)
102
103 #--------------------------------------------------------
105 if self.__inbox is None:
106 from Gnumed.business import gmProviderInbox
107 self.__inbox = gmProviderInbox.cProviderInbox(provider_id = self._payload[self._idx['pk_staff']])
108 return self.__inbox
109
112
113 inbox = property(_get_inbox, _set_inbox)
114
115 #--------------------------------------------------------
117 from Gnumed.business.gmPerson import cPerson
118 return cPerson(self._payload[self._idx['pk_identity']])
119
120 identity = property(_get_identity, lambda x:x)
121
122 #--------------------------------------------------------
124 if role.strip() == self._payload[self._idx['role']]:
125 return True
126
127 cmd = 'SELECT gm.add_user_to_permission_group(%(usr)s::name, %(grp)s::name)'
128 args = {
129 'usr': self._payload[self._idx['db_user']],
130 'grp': _map_gm_role2pg_group[role.strip()]
131 }
132 rows, idx = gmPG2.run_rw_queries (
133 link_obj = conn,
134 queries = [{'cmd': cmd, 'args': args}],
135 get_col_idx = False,
136 return_data = True,
137 end_tx = True
138 )
139 if not rows[0][0]:
140 return False
141 self.refetch_payload()
142 return True
143
144 role = property(lambda x:x, set_role)
145
146 #============================================================
148 if active_only:
149 cmd = _SQL_get_staff_fields % 'is_active ORDER BY can_login DESC, short_alias ASC'
150 else:
151 cmd = _SQL_get_staff_fields % 'TRUE ORDER BY can_login DESC, is_active DESC, short_alias ASC'
152 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
153 staff_list = []
154 for row in rows:
155 obj_row = {
156 'idx': idx,
157 'data': row,
158 'pk_field': 'pk_staff'
159 }
160 staff_list.append(cStaff(row=obj_row))
161 return staff_list
162
163 #------------------------------------------------------------
165 args = {
166 'pg_usr': db_account,
167 'pwd': password,
168 'person_id': identity,
169 'sig': short_alias
170 }
171
172 queries = [
173 {'cmd': 'SELECT gm.create_user(%(pg_usr)s, %(pwd)s)', 'args': args},
174 {'cmd': """
175 INSERT INTO dem.staff
176 (fk_identity, db_user, short_alias)
177 VALUES (
178 %(person_id)s,
179 %(pg_usr)s,
180 %(sig)s
181 )""",
182 'args': args
183 }
184 ]
185
186 created = False
187 try:
188 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
189 created = True
190 except gmPG2.dbapi.IntegrityError as e:
191 if e.pgcode != gmPG2.sql_error_codes.UNIQUE_VIOLATION:
192 raise
193
194 if created:
195 return True, None
196
197 msg = _(
198 'Cannot add GNUmed user.\n'
199 '\n'
200 'The database account [%s] is already listed as a\n'
201 'GNUmed user. There can only be one GNUmed user\n'
202 'for each database account.\n'
203 ) % db_account
204 return False, msg
205
206 #------------------------------------------------------------
208 deleted = False
209 queries = [{'cmd': 'DELETE FROM dem.staff WHERE pk = %(pk)s', 'args': {'pk': pk_staff}}]
210 try:
211 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
212 deleted = True
213 except gmPG2.dbapi.IntegrityError as e:
214 if e.pgcode != gmPG2.sql_error_codes.FOREIGN_KEY_VIOLATION: # 23503 foreign_key_violation
215 raise
216
217 if deleted:
218 return True, None
219
220 deactivate_staff(conn = conn, pk_staff = pk_staff)
221 msg = _(
222 'Cannot delete GNUmed staff member because the\n'
223 'database still contains data linked to it.\n'
224 '\n'
225 'The account was deactivated instead.'
226 )
227 return False, msg
228
229 #------------------------------------------------------------
231 # 1) activate staff entry
232 staff = cStaff(aPK_obj = pk_staff)
233 staff['is_active'] = True
234 staff.save_payload(conn=conn) # FIXME: error handling
235 # 2) enable database account login
236 rowx, idx = gmPG2.run_rw_queries (
237 link_obj = conn,
238 # password does not matter because PG account must already exist
239 queries = [{'cmd': 'select gm.create_user(%s, %s)', 'args': [staff['db_user'], 'flying wombat']}],
240 end_tx = True
241 )
242 return True
243
244 #------------------------------------------------------------
246
247 # 1) inactivate staff entry
248 staff = cStaff(aPK_obj = pk_staff)
249 staff['is_active'] = False
250 staff.save_payload(conn = conn) # FIXME: error handling
251 # 2) disable database account login
252 rows, idx = gmPG2.run_rw_queries (
253 link_obj = conn,
254 queries = [{'cmd': 'select gm.disable_user(%s)', 'args': [staff['db_user']]}],
255 end_tx = True
256 )
257 return True
258
259 #============================================================
262
263 #============================================================
265 """Staff member Borg to hold currently logged on provider.
266
267 There may be many instances of this but they all share state.
268 """
270 """Change or get currently logged on provider.
271
272 provider:
273 * None: get copy of current instance
274 * cStaff instance: change logged on provider (role)
275 """
276 # make sure we do have a provider pointer
277 try:
278 self.provider
279 except AttributeError:
280 self.provider = gmNull.cNull()
281
282 # user wants copy of currently logged on provider
283 if provider is None:
284 return None
285
286 # must be cStaff instance, then
287 if not isinstance(provider, cStaff):
288 raise ValueError('cannot set logged on provider to [%s], must be either None or cStaff instance' % str(provider))
289
290 # first invocation
291 if isinstance(self.provider, gmNull.cNull):
292 self.provider = provider
293 return None
294
295 # same ID, no change needed
296 if self.provider['pk_staff'] == provider['pk_staff']:
297 return None
298
299 # user wants different provider
300 raise ValueError('provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff']))
301
302 #--------------------------------------------------------
305
306 #--------------------------------------------------------
307 # __getitem__ handling
308 #--------------------------------------------------------
310 """Return any attribute if known how to retrieve it by proxy.
311 """
312 return self.provider[aVar]
313
314 #--------------------------------------------------------
315 # __s/getattr__ handling
316 #--------------------------------------------------------
322 # raise AttributeError
323
324 #============================================================
325 # main/testing
326 #============================================================
327 if __name__ == '__main__':
328
329 if len(sys.argv) == 1:
330 sys.exit()
331
332 if sys.argv[1] != 'test':
333 sys.exit()
334
335 import datetime
336 from Gnumed.pycommon import gmI18N
337 from Gnumed.pycommon import gmDateTime
338
339 gmI18N.activate_locale()
340 gmI18N.install_domain()
341 gmDateTime.init()
342
343 #--------------------------------------------------------
349 #--------------------------------------------------------
351 staff = cStaff()
352 provider = gmCurrentProvider(provider = staff)
353 print(provider)
354 print(provider.inbox)
355 print(provider.inbox.messages)
356 print(provider.database_language)
357 tmp = provider.database_language
358 provider.database_language = None
359 print(provider.database_language)
360 provider.database_language = tmp
361 print(provider.database_language)
362 #--------------------------------------------------------
363 test_staff()
364 #test_current_provider()
365
366 #============================================================
367
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Feb 29 02:55:27 2020 | http://epydoc.sourceforge.net |