1
2 """GNUmed staff objects."""
3
4 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
5 __license__ = "GPL"
6
7
8 import sys
9 import logging
10
11
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
32 -class cStaff(gmBusinessDBObject.cBusinessDBObject):
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
50 - def __init__(self, aPK_obj=None, row=None):
75
76
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
109
112
113 inbox = property(_get_inbox, _set_inbox)
114
115
119
120 identity = property(_get_identity, lambda x:x)
121
122
123 - def set_role(self, conn=None, role=None):
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
164 -def create_staff(conn=None, db_account=None, password=None, identity=None, short_alias=None):
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:
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
232 staff = cStaff(aPK_obj = pk_staff)
233 staff['is_active'] = True
234 staff.save_payload(conn=conn)
235
236 rowx, idx = gmPG2.run_rw_queries (
237 link_obj = conn,
238
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
248 staff = cStaff(aPK_obj = pk_staff)
249 staff['is_active'] = False
250 staff.save_payload(conn = conn)
251
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
277 try:
278 self.provider
279 except AttributeError:
280 self.provider = gmNull.cNull()
281
282
283 if provider is None:
284 return None
285
286
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
291 if isinstance(self.provider, gmNull.cNull):
292 self.provider = provider
293 return None
294
295
296 if self.provider['pk_staff'] == provider['pk_staff']:
297 return None
298
299
300 raise ValueError('provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff']))
301
302
305
306
307
308
310 """Return any attribute if known how to retrieve it by proxy.
311 """
312 return self.provider[aVar]
313
314
315
316
318 if attribute == 'provider':
319 raise AttributeError
320 if not isinstance(self.provider, gmNull.cNull):
321 return getattr(self.provider, attribute)
322
323
324
325
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
362
363 test_staff()
364
365
366
367