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 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
32 -class cStaff(gmBusinessDBObject.cBusinessDBObject):
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
49 - def __init__(self, aPK_obj=None, row=None):
75
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
106
109
110 inbox = property(_get_inbox, _set_inbox)
111
115
116 identity = property(_get_identity, lambda x:x)
117
118 - def set_role(self, conn=None, role=None):
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
157 -def create_staff(conn=None, db_account=None, password=None, identity=None, short_alias=None):
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:
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
215 staff = cStaff(aPK_obj = pk_staff)
216 staff['is_active'] = True
217 staff.save_payload(conn=conn)
218
219
220 rowx, idx = gmPG2.run_rw_queries (
221 link_obj = conn,
222
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
232 staff = cStaff(aPK_obj = pk_staff)
233 staff['is_active'] = False
234 staff.save_payload(conn = conn)
235
236
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
261 try:
262 self.provider
263 except AttributeError:
264 self.provider = gmNull.cNull()
265
266
267 if provider is None:
268 return None
269
270
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
275 if self.provider['pk_staff'] == provider['pk_staff']:
276 return None
277
278
279 if isinstance(self.provider, gmNull.cNull):
280 self.provider = provider
281 return None
282
283
284 raise ValueError, 'provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff'])
285
286
289
290
291
293 """Return any attribute if known how to retrieve it by proxy.
294 """
295 return self.provider[aVar]
296
297
298
300 if attribute == 'provider':
301 raise AttributeError
302 if not isinstance(self.provider, gmNull.cNull):
303 return getattr(self.provider, attribute)
304
305
306
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
343
344 test_staff()
345
346
347
348