| 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:
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 try:
187 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
188 except gmPG2.dbapi.IntegrityError as e:
189 if e.pgcode == gmPG2.sql_error_codes.UNIQUE_VIOLATION:
190 msg = _(
191 'Cannot add GNUmed user.\n'
192 '\n'
193 'The database account [%s] is already listed as a\n'
194 'GNUmed user. There can only be one GNUmed user\n'
195 'for each database account.\n'
196 ) % db_account
197 return False, msg
198 raise
199
200 return True, None
201
202 #------------------------------------------------------------
204 queries = [{'cmd': 'DELETE FROM dem.staff WHERE pk = %(pk)s', 'args': {'pk': pk_staff}}]
205 try:
206 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
207 except gmPG2.dbapi.IntegrityError as e:
208 if e.pgcode == gmPG2.sql_error_codes.FOREIGN_KEY_VIOLATION: # 23503 foreign_key_violation
209 msg = _(
210 'Cannot delete GNUmed staff member because the\n'
211 'database still contains data linked to it.\n'
212 '\n'
213 'The account was deactivated instead.'
214 )
215 deactivate_staff(conn = conn, pk_staff = pk_staff)
216 return False, msg
217 raise
218
219 return True, None
220
221 #------------------------------------------------------------
223 # 1) activate staff entry
224 staff = cStaff(aPK_obj = pk_staff)
225 staff['is_active'] = True
226 staff.save_payload(conn=conn) # FIXME: error handling
227
228 # 2) enable database account login
229 rowx, idx = gmPG2.run_rw_queries (
230 link_obj = conn,
231 # password does not matter because PG account must already exist
232 queries = [{'cmd': 'select gm.create_user(%s, %s)', 'args': [staff['db_user'], 'flying wombat']}],
233 end_tx = True
234 )
235
236 return True
237
238 #------------------------------------------------------------
240
241 # 1) inactivate staff entry
242 staff = cStaff(aPK_obj = pk_staff)
243 staff['is_active'] = False
244 staff.save_payload(conn = conn) # FIXME: error handling
245
246 # 2) disable database account login
247 rows, idx = gmPG2.run_rw_queries (
248 link_obj = conn,
249 queries = [{'cmd': 'select gm.disable_user(%s)', 'args': [staff['db_user']]}],
250 end_tx = True
251 )
252
253 return True
254
255 #============================================================
258
259 #============================================================
261 """Staff member Borg to hold currently logged on provider.
262
263 There may be many instances of this but they all share state.
264 """
266 """Change or get currently logged on provider.
267
268 provider:
269 * None: get copy of current instance
270 * cStaff instance: change logged on provider (role)
271 """
272 # make sure we do have a provider pointer
273 try:
274 self.provider
275 except AttributeError:
276 self.provider = gmNull.cNull()
277
278 # user wants copy of currently logged on provider
279 if provider is None:
280 return None
281
282 # must be cStaff instance, then
283 if not isinstance(provider, cStaff):
284 raise ValueError('cannot set logged on provider to [%s], must be either None or cStaff instance' % str(provider))
285
286 # first invocation
287 if isinstance(self.provider, gmNull.cNull):
288 self.provider = provider
289 return None
290
291 # same ID, no change needed
292 if self.provider['pk_staff'] == provider['pk_staff']:
293 return None
294
295 # user wants different provider
296 raise ValueError('provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff']))
297
298 #--------------------------------------------------------
301
302 #--------------------------------------------------------
303 # __getitem__ handling
304 #--------------------------------------------------------
306 """Return any attribute if known how to retrieve it by proxy.
307 """
308 return self.provider[aVar]
309
310 #--------------------------------------------------------
311 # __s/getattr__ handling
312 #--------------------------------------------------------
318 # raise AttributeError
319
320 #============================================================
321 # main/testing
322 #============================================================
323 if __name__ == '__main__':
324
325 if len(sys.argv) == 1:
326 sys.exit()
327
328 if sys.argv[1] != 'test':
329 sys.exit()
330
331 import datetime
332 from Gnumed.pycommon import gmI18N
333 from Gnumed.pycommon import gmDateTime
334
335 gmI18N.activate_locale()
336 gmI18N.install_domain()
337 gmDateTime.init()
338
339 #--------------------------------------------------------
345 #--------------------------------------------------------
347 staff = cStaff()
348 provider = gmCurrentProvider(provider = staff)
349 print(provider)
350 print(provider.inbox)
351 print(provider.inbox.messages)
352 print(provider.database_language)
353 tmp = provider.database_language
354 provider.database_language = None
355 print(provider.database_language)
356 provider.database_language = tmp
357 print(provider.database_language)
358 #--------------------------------------------------------
359 test_staff()
360 #test_current_provider()
361
362 #============================================================
363
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Jan 25 02:55:27 2019 | http://epydoc.sourceforge.net |