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_fetch_staff_fields = 'SELECT *, _(role) AS l10n_role FROM dem.v_staff WHERE %s'
31
32 -class cStaff(gmBusinessDBObject.cBusinessDBObject):
33 _cmd_fetch_payload = _SQL_fetch_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_fetch_staff_fields % 'is_active ORDER BY can_login DESC, short_alias ASC'
150 else:
151 cmd = _SQL_fetch_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 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:
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
224 staff = cStaff(aPK_obj = pk_staff)
225 staff['is_active'] = True
226 staff.save_payload(conn=conn)
227
228
229 rowx, idx = gmPG2.run_rw_queries (
230 link_obj = conn,
231
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
242 staff = cStaff(aPK_obj = pk_staff)
243 staff['is_active'] = False
244 staff.save_payload(conn = conn)
245
246
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
273 try:
274 self.provider
275 except AttributeError:
276 self.provider = gmNull.cNull()
277
278
279 if provider is None:
280 return None
281
282
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
287 if isinstance(self.provider, gmNull.cNull):
288 self.provider = provider
289 return None
290
291
292 if self.provider['pk_staff'] == provider['pk_staff']:
293 return None
294
295
296 raise ValueError('provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff']))
297
298
301
302
303
304
306 """Return any attribute if known how to retrieve it by proxy.
307 """
308 return self.provider[aVar]
309
310
311
312
314 if attribute == 'provider':
315 raise AttributeError
316 if not isinstance(self.provider, gmNull.cNull):
317 return getattr(self.provider, attribute)
318
319
320
321
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
358
359 test_staff()
360
361
362
363