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': '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   
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 '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 #------------------------------------------------------------
196 -def delete_staff(conn=None, pk_staff=None):
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 #------------------------------------------------------------
214 -def activate_staff(conn=None, pk_staff=None):
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 #------------------------------------------------------------
230 -def deactivate_staff(conn=None, pk_staff=None):
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 #============================================================
246 -def set_current_provider_to_logged_on_user():
247 gmCurrentProvider(provider = cStaff())
248 #============================================================
249 -class gmCurrentProvider(gmBorg.cBorg):
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 """
254 - def __init__(self, provider=None):
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 #--------------------------------------------------------
288 - def get_staff(self):
289 return self.provider
290 #-------------------------------------------------------- 291 # __getitem__ handling 292 #--------------------------------------------------------
293 - def __getitem__(self, aVar):
294 """Return any attribute if known how to retrieve it by proxy. 295 """ 296 return self.provider[aVar]
297 #-------------------------------------------------------- 298 # __s/getattr__ handling 299 #--------------------------------------------------------
300 - def __getattr__(self, attribute):
301 if attribute == 'provider': # so we can __init__ ourselves 302 raise AttributeError 303 if not isinstance(self.provider, gmNull.cNull): 304 return getattr(self.provider, attribute)
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 #--------------------------------------------------------
326 - def test_staff():
327 staff = cStaff() 328 print staff 329 print staff.inbox 330 print staff.inbox.messages
331 #--------------------------------------------------------
332 - def test_current_provider():
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