| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf8 -*-
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 u'public': 'gm-public',
25 u'staff': u'gm-staff',
26 u'doctor': u'gm-doctors'
27 }
28
29 #============================================================
30 _SQL_fetch_staff_fields = u'SELECT *, _(role) AS l10n_role FROM dem.v_staff WHERE %s'
31
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 #--------------------------------------------------------
50 # by default get staff corresponding to CURRENT_USER
51 if (aPK_obj is None) and (row is None):
52 #cmd = u"select *, _(role) AS l10n_role from dem.v_staff where "
53 cmd = _SQL_fetch_staff_fields % u"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 #--------------------------------------------------------
77 if attribute == 'db_user':
78 if self.__is_current_user:
79 _log.debug('will not modify database account association of CURRENT_USER staff member')
80 return
81 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
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 #--------------------------------------------------------
102 if self.__inbox is None:
103 from Gnumed.business import gmProviderInbox
104 self.__inbox = gmProviderInbox.cProviderInbox(provider_id = self._payload[self._idx['pk_staff']])
105 return self.__inbox
106
109
110 inbox = property(_get_inbox, _set_inbox)
111 #--------------------------------------------------------
113 from Gnumed.business import gmPerson
114 return gmPerson.cIdentity(aPK_obj = self._payload[self._idx['pk_identity']])
115
116 identity = property(_get_identity, lambda x:x)
117 #--------------------------------------------------------
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 #------------------------------------------------------------
158 args = {
159 'pg_usr': db_account,
160 'pwd': password,
161 'person_id': identity,
162 'sig': short_alias,
163 'gm_role_name': u'doctor'
164 }
165
166 queries = [
167 {'cmd': u'SELECT gm.create_user(%(pg_usr)s, %(pwd)s)', 'args': args},
168 {'cmd': u"""
169 INSERT INTO dem.staff
170 (fk_identity, db_user, short_alias)
171 VALUES (
172 %(person_id)s,
173 %(pg_usr)s,
174 %(sig)s
175 )""",
176 'args': args
177 }
178 ]
179
180 try:
181 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
182 except gmPG2.dbapi.IntegrityError, e:
183 if e.pgcode == gmPG2.sql_error_codes.UNIQUE_VIOLATION:
184 msg = _(
185 'Cannot add GNUmed user.\n'
186 '\n'
187 'The database account [%s] is already listed as a\n'
188 'GNUmed user. There can only be one GNUmed user\n'
189 'for each database account.\n'
190 ) % db_account
191 return False, msg
192 raise
193
194 return True, None
195 #------------------------------------------------------------
197 queries = [{'cmd': u'DELETE FROM dem.staff WHERE pk = %(pk)s', 'args': {'pk': pk_staff}}]
198 try:
199 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
200 except gmPG2.dbapi.IntegrityError, e:
201 if e.pgcode == gmPG2.sql_error_codes.FOREIGN_KEY_VIOLATION: # 23503 foreign_key_violation
202 msg = _(
203 'Cannot delete GNUmed staff member because the\n'
204 'database still contains data linked to it.\n'
205 '\n'
206 'The account was deactivated instead.'
207 )
208 deactivate_staff(conn = conn, pk_staff = pk_staff)
209 return False, msg
210 raise
211
212 return True, None
213 #------------------------------------------------------------
215 # 1) activate staff entry
216 staff = cStaff(aPK_obj = pk_staff)
217 staff['is_active'] = True
218 staff.save_payload(conn=conn) # FIXME: error handling
219
220 # 2) enable database account login
221 rowx, idx = gmPG2.run_rw_queries (
222 link_obj = conn,
223 # password does not matter because PG account must already exist
224 queries = [{'cmd': u'select gm.create_user(%s, %s)', 'args': [staff['db_user'], 'flying wombat']}],
225 end_tx = True
226 )
227
228 return True
229 #------------------------------------------------------------
231
232 # 1) inactivate staff entry
233 staff = cStaff(aPK_obj = pk_staff)
234 staff['is_active'] = False
235 staff.save_payload(conn = conn) # FIXME: error handling
236
237 # 2) disable database account login
238 rows, idx = gmPG2.run_rw_queries (
239 link_obj = conn,
240 queries = [{'cmd': u'select gm.disable_user(%s)', 'args': [staff['db_user']]}],
241 end_tx = True
242 )
243
244 return True
245 #============================================================
248 #============================================================
250 """Staff member Borg to hold currently logged on provider.
251
252 There may be many instances of this but they all share state.
253 """
255 """Change or get currently logged on provider.
256
257 provider:
258 * None: get copy of current instance
259 * cStaff instance: change logged on provider (role)
260 """
261 # make sure we do have a provider pointer
262 try:
263 self.provider
264 except AttributeError:
265 self.provider = gmNull.cNull()
266
267 # user wants copy of currently logged on provider
268 if provider is None:
269 return None
270
271 # must be cStaff instance, then
272 if not isinstance(provider, cStaff):
273 raise ValueError, 'cannot set logged on provider to [%s], must be either None or cStaff instance' % str(provider)
274
275 # same ID, no change needed
276 if self.provider['pk_staff'] == provider['pk_staff']:
277 return None
278
279 # first invocation
280 if isinstance(self.provider, gmNull.cNull):
281 self.provider = provider
282 return None
283
284 # user wants different provider
285 raise ValueError, 'provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff'])
286
287 #--------------------------------------------------------
290 #--------------------------------------------------------
291 # __getitem__ handling
292 #--------------------------------------------------------
294 """Return any attribute if known how to retrieve it by proxy.
295 """
296 return self.provider[aVar]
297 #--------------------------------------------------------
298 # __s/getattr__ handling
299 #--------------------------------------------------------
305 # raise AttributeError
306 #============================================================
307 # main/testing
308 #============================================================
309 if __name__ == '__main__':
310
311 if len(sys.argv) == 1:
312 sys.exit()
313
314 if sys.argv[1] != 'test':
315 sys.exit()
316
317 import datetime
318 from Gnumed.pycommon import gmI18N
319 from Gnumed.pycommon import gmDateTime
320
321 gmI18N.activate_locale()
322 gmI18N.install_domain()
323 gmDateTime.init()
324
325 #--------------------------------------------------------
331 #--------------------------------------------------------
333 staff = cStaff()
334 provider = gmCurrentProvider(provider = staff)
335 print provider
336 print provider.inbox
337 print provider.inbox.messages
338 print provider.database_language
339 tmp = provider.database_language
340 provider.database_language = None
341 print provider.database_language
342 provider.database_language = tmp
343 print provider.database_language
344 #--------------------------------------------------------
345 test_staff()
346 #test_current_provider()
347
348 #============================================================
349
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Jul 12 03:56:51 2013 | http://epydoc.sourceforge.net |