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  #============================================================
     24 -class cStaff(gmBusinessDBObject.cBusinessDBObject):
     25          _cmd_fetch_payload = u"SELECT * FROM dem.v_staff WHERE pk_staff = %s"
     26          _cmds_store_payload = [
     27                  u"""UPDATE dem.staff SET
     28                                  fk_role = %(pk_role)s,
     29                                  short_alias = %(short_alias)s,
     30                                  comment = gm.nullify_empty_string(%(comment)s),
     31                                  is_active = %(is_active)s,
     32                                  db_user = %(db_user)s
     33                          WHERE
     34                                  pk = %(pk_staff)s
     35                                          AND
     36                                  xmin = %(xmin_staff)s
     37                          RETURNING
     38                                  xmin AS xmin_staff"""
     39          ]
     40          _updatable_fields = ['pk_role', 'short_alias', 'comment', 'is_active', 'db_user']
     41          #--------------------------------------------------------
     42 -        def __init__(self, aPK_obj=None, row=None):
     43                  # by default get staff corresponding to CURRENT_USER
     44                  if (aPK_obj is None) and (row is None):
     45                          cmd = u"select * from dem.v_staff where db_user = CURRENT_USER"
     46                          try:
     47                                  rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
     48                          except:
     49                                  _log.exception('cannot instantiate staff instance')
     50                                  gmLog2.log_stack_trace()
     51                                  raise ValueError('cannot instantiate staff instance for database account CURRENT_USER')
     52                          if len(rows) == 0:
     53                                  raise ValueError('no staff record for database account CURRENT_USER')
     54                          row = {
     55                                  'pk_field': 'pk_staff',
     56                                  'idx': idx,
     57                                  'data': rows[0]
     58                          }
     59                          gmBusinessDBObject.cBusinessDBObject.__init__(self, row = row)
     60                  else:
     61                          gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj = aPK_obj, row = row)
     62
     63                  # are we SELF ?
     64                  self.__is_current_user = (gmPG2.get_current_user() == self._payload[self._idx['db_user']])
     65
     66                  self.__inbox = None
     67          #--------------------------------------------------------
     68 -        def __setitem__(self, attribute, value):
     69                  if attribute == 'db_user':
     70                          if self.__is_current_user:
     71                                  _log.debug('will not modify database account association of CURRENT_USER staff member')
     72                                  return
     73                  gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
     74          #--------------------------------------------------------
     75 -        def _get_db_lang(self):
     76                  rows, idx = gmPG2.run_ro_queries (
     77                          queries = [{
     78                                  'cmd': u'select i18n.get_curr_lang(%(usr)s)',
     79                                  'args': {'usr': self._payload[self._idx['db_user']]}
     80                          }]
     81                  )
     82                  return rows[0][0]
     83
     84 -        def _set_db_lang(self, language):
     85                  if not gmPG2.set_user_language(language = language):
     86                          raise ValueError (
     87                                  u'Cannot set database language to [%s] for user [%s].' % (language, self._payload[self._idx['db_user']])
     88                          )
     89                  return
     90
     91          database_language = property(_get_db_lang, _set_db_lang)
     92          #--------------------------------------------------------
     93 -        def _get_inbox(self):
     94                  if self.__inbox is None:
     95                          from Gnumed.business import gmProviderInbox
     96                          self.__inbox = gmProviderInbox.cProviderInbox(provider_id = self._payload[self._idx['pk_staff']])
     97                  return self.__inbox
     98
     99 -        def _set_inbox(self, inbox):
    100                  return
    101
    102          inbox = property(_get_inbox, _set_inbox)
    103          #--------------------------------------------------------
    104 -        def _get_identity(self):
    105                  from Gnumed.business import gmPerson
    106                  return gmPerson.cIdentity(aPK_obj = self._payload[self._idx['pk_identity']])
    107
    108          identity = property(_get_identity, lambda x:x)
    109  #============================================================
    110 -def get_staff_list(active_only=False):
    111          if active_only:
    112                  cmd = u"SELECT * FROM dem.v_staff WHERE is_active ORDER BY can_login DESC, short_alias ASC"
    113          else:
    114                  cmd = u"SELECT * FROM dem.v_staff ORDER BY can_login desc, is_active desc, short_alias ASC"
    115          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx=True)
    116          staff_list = []
    117          for row in rows:
    118                  obj_row = {
    119                          'idx': idx,
    120                          'data': row,
    121                          'pk_field': 'pk_staff'
    122                  }
    123                  staff_list.append(cStaff(row=obj_row))
    124          return staff_list
    125  #------------------------------------------------------------
    126 -def create_staff(conn=None, db_account=None, password=None, identity=None, short_alias=None):
    127          args = {
    128                  'pg_usr': db_account,
    129                  'pwd': password,
    130                  'person_id': identity,
    131                  'sig': short_alias,
    132                  'gm_role_name': u'doctor'
    133          }
    134
    135          queries = [
    136                  {'cmd': u'SELECT gm.create_user(%(pg_usr)s, %(pwd)s)', 'args': args},
    137                  {'cmd': u"""
    138                          INSERT INTO dem.staff
    139                                  (fk_identity, fk_role, db_user, short_alias)
    140                          VALUES (
    141                                  %(person_id)s,
    142                                  (SELECT pk FROM dem.staff_role WHERE name = %(gm_role_name)s),
    143                                  %(pg_usr)s,
    144                                  %(sig)s
    145                          )""",
    146                   'args': args
    147                  }
    148          ]
    149
    150          try:
    151                  rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
    152          except gmPG2.dbapi.IntegrityError, e:
    153                  if e.pgcode == gmPG2.sql_error_codes.UNIQUE_VIOLATION:
    154                          msg = _(
    155                                  'Cannot add GNUmed user.\n'
    156                                  '\n'
    157                                  'The database account [%s] is already listed as a\n'
    158                                  'GNUmed user. There can only be one GNUmed user\n'
    159                                  'for each database account.\n'
    160                          ) % db_account
    161                          return False, msg
    162                  raise
    163
    164          return True, None
    165  #------------------------------------------------------------
    166 -def delete_staff(conn=None, pk_staff=None):
    167          queries = [{'cmd': u'DELETE FROM dem.staff WHERE pk = %(pk)s', 'args': {'pk': pk_staff}}]
    168          try:
    169                  rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
    170          except gmPG2.dbapi.IntegrityError, e:
    171                  if e.pgcode == gmPG2.sql_error_codes.FOREIGN_KEY_VIOLATION:             # 23503  foreign_key_violation
    172                          msg = _(
    173                                  'Cannot delete GNUmed staff member because the\n'
    174                                  'database still contains data linked to it.\n'
    175                                  '\n'
    176                                  'The account was deactivated instead.'
    177                          )
    178                          deactivate_staff(conn = conn, pk_staff = pk_staff)
    179                          return False, msg
    180                  raise
    181
    182          return True, None
    183  #------------------------------------------------------------
    184 -def activate_staff(conn=None, pk_staff=None):
    185          # 1) activate staff entry
    186          staff = cStaff(aPK_obj = pk_staff)
    187          staff['is_active'] = True
    188          staff.save_payload(conn=conn)                           # FIXME: error handling
    189
    190          # 2) enable database account login
    191          rowx, idx = gmPG2.run_rw_queries (
    192                  link_obj = conn,
    193                  # password does not matter because PG account must already exist
    194                  queries = [{'cmd': u'select gm.create_user(%s, %s)', 'args': [staff['db_user'], 'flying wombat']}],
    195                  end_tx = True
    196          )
    197
    198          return True
    199  #------------------------------------------------------------
    200 -def deactivate_staff(conn=None, pk_staff=None):
    201
    202          # 1) inactivate staff entry
    203          staff = cStaff(aPK_obj = pk_staff)
    204          staff['is_active'] = False
    205          staff.save_payload(conn = conn)                         # FIXME: error handling
    206
    207          # 2) disable database account login
    208          rows, idx = gmPG2.run_rw_queries (
    209                  link_obj = conn,
    210                  queries = [{'cmd': u'select gm.disable_user(%s)', 'args': [staff['db_user']]}],
    211                  end_tx = True
    212          )
    213
    214          return True
    215  #============================================================
    216 -def set_current_provider_to_logged_on_user():
    217          gmCurrentProvider(provider = cStaff())
    218  #============================================================
    219 -class gmCurrentProvider(gmBorg.cBorg):
    220          """Staff member Borg to hold currently logged on provider.
    221
    222          There may be many instances of this but they all share state.
    223          """
    224 -        def __init__(self, provider=None):
    225                  """Change or get currently logged on provider.
    226
    227                  provider:
    228                  * None: get copy of current instance
    229                  * cStaff instance: change logged on provider (role)
    230                  """
    231                  # make sure we do have a provider pointer
    232                  try:
    233                          self.provider
    234                  except AttributeError:
    235                          self.provider = gmNull.cNull()
    236
    237                  # user wants copy of currently logged on provider
    238                  if provider is None:
    239                          return None
    240
    241                  # must be cStaff instance, then
    242                  if not isinstance(provider, cStaff):
    243                          raise ValueError, 'cannot set logged on provider to [%s], must be either None or cStaff instance' % str(provider)
    244
    245                  # same ID, no change needed
    246                  if self.provider['pk_staff'] == provider['pk_staff']:
    247                          return None
    248
    249                  # first invocation
    250                  if isinstance(self.provider, gmNull.cNull):
    251                          self.provider = provider
    252                          return None
    253
    254                  # user wants different provider
    255                  raise ValueError, 'provider change [%s] -> [%s] not yet supported' % (self.provider['pk_staff'], provider['pk_staff'])
    256
    257          #--------------------------------------------------------
    258 -        def get_staff(self):
    259                  return self.provider
    260          #--------------------------------------------------------
    261          # __getitem__ handling
    262          #--------------------------------------------------------
    263 -        def __getitem__(self, aVar):
    264                  """Return any attribute if known how to retrieve it by proxy.
    265                  """
    266                  return self.provider[aVar]
    267          #--------------------------------------------------------
    268          # __s/getattr__ handling
    269          #--------------------------------------------------------
    270 -        def __getattr__(self, attribute):
    271                  if attribute == 'provider':                     # so we can __init__ ourselves
    272                          raise AttributeError
    273                  if not isinstance(self.provider, gmNull.cNull):
    274                          return getattr(self.provider, attribute)
    275  #               raise AttributeError
    276  #============================================================
    277  # main/testing
    278  #============================================================
    279  if __name__ == '__main__':
    280
    281          if len(sys.argv) == 1:
    282                  sys.exit()
    283
    284          if sys.argv[1] != 'test':
    285                  sys.exit()
    286
    287          import datetime
    288          from Gnumed.pycommon import gmI18N
    289          from Gnumed.pycommon import gmDateTime
    290
    291          gmI18N.activate_locale()
    292          gmI18N.install_domain()
    293          gmDateTime.init()
    294
    295          #--------------------------------------------------------
    296 -        def test_staff():
    297                  staff = cStaff()
    298                  print staff
    299                  print staff.inbox
    300                  print staff.inbox.messages
    301          #--------------------------------------------------------
    302 -        def test_current_provider():
    303                  staff = cStaff()
    304                  provider = gmCurrentProvider(provider = staff)
    305                  print provider
    306                  print provider.inbox
    307                  print provider.inbox.messages
    308                  print provider.database_language
    309                  tmp = provider.database_language
    310                  provider.database_language = None
    311                  print provider.database_language
    312                  provider.database_language = tmp
    313                  print provider.database_language
    314          #--------------------------------------------------------
    315          test_staff()
    316          #test_current_provider()
    317
    318  #============================================================
    319