Package Gnumed :: Package business :: Module gmStaff
[frames] | no frames]

Source Code for Module Gnumed.business.gmStaff

  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 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):
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 #--------------------------------------------------------
76 - def __setitem__(self, attribute, value):
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 #--------------------------------------------------------
83 - def _get_db_lang(self):
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
92 - def _set_db_lang(self, language):
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 #--------------------------------------------------------
101 - def _get_inbox(self):
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
107 - def _set_inbox(self, inbox):
108 return
109 110 inbox = property(_get_inbox, _set_inbox) 111 #--------------------------------------------------------
112 - def _get_identity(self):
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 #--------------------------------------------------------
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 #============================================================
141 -def get_staff_list(active_only=False):
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 #------------------------------------------------------------
195 -def delete_staff(conn=None, pk_staff=None):
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: # 23503 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 #------------------------------------------------------------
213 -def activate_staff(conn=None, pk_staff=None):
214 # 1) activate staff entry 215 staff = cStaff(aPK_obj = pk_staff) 216 staff['is_active'] = True 217 staff.save_payload(conn=conn) # FIXME: error handling 218 219 # 2) enable database account login 220 rowx, idx = gmPG2.run_rw_queries ( 221 link_obj = conn, 222 # password does not matter because PG account must already exist 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 #------------------------------------------------------------
229 -def deactivate_staff(conn=None, pk_staff=None):
230 231 # 1) inactivate staff entry 232 staff = cStaff(aPK_obj = pk_staff) 233 staff['is_active'] = False 234 staff.save_payload(conn = conn) # FIXME: error handling 235 236 # 2) disable database account login 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 #============================================================
245 -def set_current_provider_to_logged_on_user():
246 gmCurrentProvider(provider = cStaff())
247 #============================================================
248 -class gmCurrentProvider(gmBorg.cBorg):
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 """
253 - def __init__(self, provider=None):
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 # make sure we do have a provider pointer 261 try: 262 self.provider 263 except AttributeError: 264 self.provider = gmNull.cNull() 265 266 # user wants copy of currently logged on provider 267 if provider is None: 268 return None 269 270 # must be cStaff instance, then 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 # same ID, no change needed 275 if self.provider['pk_staff'] == provider['pk_staff']: 276 return None 277 278 # first invocation 279 if isinstance(self.provider, gmNull.cNull): 280 self.provider = provider 281 return None 282 283 # user wants different provider 284 raise ValueError, 'provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff'])
285 286 #--------------------------------------------------------
287 - def get_staff(self):
288 return self.provider
289 #-------------------------------------------------------- 290 # __getitem__ handling 291 #--------------------------------------------------------
292 - def __getitem__(self, aVar):
293 """Return any attribute if known how to retrieve it by proxy. 294 """ 295 return self.provider[aVar]
296 #-------------------------------------------------------- 297 # __s/getattr__ handling 298 #--------------------------------------------------------
299 - def __getattr__(self, attribute):
300 if attribute == 'provider': # so we can __init__ ourselves 301 raise AttributeError 302 if not isinstance(self.provider, gmNull.cNull): 303 return getattr(self.provider, attribute)
304 # raise AttributeError 305 #============================================================ 306 # main/testing 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 #--------------------------------------------------------
325 - def test_staff():
326 staff = cStaff() 327 print staff 328 print staff.inbox 329 print staff.inbox.messages
330 #--------------------------------------------------------
331 - def test_current_provider():
332 staff = cStaff() 333 provider = gmCurrentProvider(provider = staff) 334 print provider 335 print provider.inbox 336 print provider.inbox.messages 337 print provider.database_language 338 tmp = provider.database_language 339 provider.database_language = None 340 print provider.database_language 341 provider.database_language = tmp 342 print provider.database_language
343 #-------------------------------------------------------- 344 test_staff() 345 #test_current_provider() 346 347 #============================================================ 348