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

# Source Code for Module Gnumed.business.gmFamilyHistory

      1  """GNUmed family history handling middleware"""
      2  #============================================================
      3  __license__ = "GPL"
      4  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
      5
      6
      7  # stdlib
      8  import sys, logging
      9
     10
     11  # GNUmed modules
     12  if __name__ == '__main__':
     13          sys.path.insert(0, '../../')
     14  from Gnumed.pycommon import gmPG2
     15  from Gnumed.pycommon import gmBusinessDBObject
     16  from Gnumed.pycommon import gmDateTime
     17  from Gnumed.pycommon import gmTools
     18
     19  from Gnumed.business import gmCoding
     20
     21
     22  _log = logging.getLogger('gm.fhx')
     23
     24  #============================================================
     25  # relationship type handling
     26  #------------------------------------------------------------
     27 -def create_relationship_type(relationship=None, genetic=None):
     28
     29          args = {'rel': relationship, 'gen': genetic}
     30
     31          # already exists ?
     32          cmd = u"""
     33                  SELECT *, _(description) as l10n_description
     34                  FROM clin.fhx_relation_type
     35                  WHERE
     36                          description = %(rel)s
     37                                  OR
     38                          _(description) = %(rel)s
     39          """
     40          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
     41          if len(rows) > 0:
     42                  return rows[0]
     43
     44          # create it
     45          cmd = u"""
     46                  INSERT INTO clin.fhx_relation_type (
     47                          description,
     48                          is_genetic
     49                  ) VALUES (
     50                          i18n.i18n(gm.nullify_empty_string(%(rel)s)),
     51                          %(gen)s
     52                  )
     53                  RETURNING *
     54          """
     55          rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
     56          return rows[0]
     57  #============================================================
     58  # Family History item handling
     59  #------------------------------------------------------------
     60  _SQL_get_family_history = u"SELECT * from clin.v_family_history WHERE %s"
     61
     62 -class cFamilyHistory(gmBusinessDBObject.cBusinessDBObject):
     63          """Represents a Family History item."""
     64
     65          _cmd_fetch_payload = _SQL_get_family_history % u"pk_family_history = %s"
     66          _cmds_store_payload = [
     67                  u"""
     68                          UPDATE clin.family_history SET
     69                                  narrative = gm.nullify_empty_string(%(condition)s),
     70                                  age_noted = gm.nullify_empty_string(%(age_noted)s),
     71                                  age_of_death = %(age_of_death)s,
     72                                  contributed_to_death = %(contributed_to_death)s,
     73                                  clin_when = %(when_known_to_patient)s,
     74                                  name_relative = gm.nullify_empty_string(%(name_relative)s),
     75                                  dob_relative = %(dob_relative)s,
     76                                  comment = gm.nullify_empty_string(%(comment)s),
     77                                  fk_episode = %(pk_episode)s,
     78                                  fk_relation_type = %(pk_fhx_relation_type)s
     79                          WHERE
     80                                  pk = %(pk_family_history)s
     81                                          AND
     82                                  xmin = %(xmin_family_history)s
     83                          RETURNING
     84                                  pk as pk_family_history,
     85                                  xmin as xmin_family_history
     86                  """
     87          ]
     88          # view columns that can be updated:
     89          _updatable_fields = [
     90                  u'condition',
     91                  u'age_noted',
     92                  u'age_of_death',
     93                  u'contributed_to_death',
     94                  u'when_known_to_patient',
     95                  u'name_relative',
     96                  u'dob_relative',
     97                  u'pk_encounter',
     98                  u'pk_episode',
     99                  u'pk_fhx_relation_type',
    100                  u'comment'
    101          ]
    102          #--------------------------------------------------------
    103 -        def add_code(self, pk_code=None):
    104                  """<pk_code> must be a value from ref.coding_system_root.pk_coding_system (clin.lnk_code2item_root.fk_generic_code)"""
    105
    106                  if pk_code in self._payload[self._idx['pk_generic_codes']]:
    107                          return
    108
    109                  cmd = u"""
    110                          INSERT INTO clin.lnk_code2fhx
    111                                  (fk_item, fk_generic_code)
    112                          SELECT
    113                                  %(item)s,
    114                                  %(code)s
    115                          WHERE NOT EXISTS (
    116                                  SELECT 1 FROM clin.lnk_code2fhx
    117                                  WHERE
    118                                          fk_item = %(item)s
    119                                                  AND
    120                                          fk_generic_code = %(code)s
    121                          )"""
    122                  args = {
    123                          'item': self._payload[self._idx['pk_family_history']],
    124                          'code': pk_code
    125                  }
    126                  rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    127                  return
    128          #--------------------------------------------------------
    129 -        def remove_code(self, pk_code=None):
    130                  """<pk_code> must be a value from ref.coding_system_root.pk_coding_system (clin.lnk_code2item_root.fk_generic_code)"""
    131                  cmd = u"DELETE FROM clin.lnk_code2fhx WHERE fk_item = %(item)s AND fk_generic_code = %(code)s"
    132                  args = {
    133                          'item': self._payload[self._idx['pk_family_history']],
    134                          'code': pk_code
    135                  }
    136                  rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    137                  return True
    138          #--------------------------------------------------------
    139 -        def format(self, left_margin=0, include_episode=False, include_comment=False, include_codes=False):
    140
    141                  line = u'%s%s' % (
    142                          (u' ' * left_margin),
    143                          self._payload[self._idx['l10n_relation']]
    144                  )
    145                  if self._payload[self._idx['age_of_death']] is not None:
    146                          line += u' (%s %s)' % (
    147                                  gmTools.u_latin_cross,
    148                                  gmDateTime.format_interval_medically(self._payload[self._idx['age_of_death']])
    149                          )
    150                  line += u': %s' % self._payload[self._idx['condition']]
    151                  if self._payload[self._idx['age_noted']] is not None:
    152                          line += gmTools.coalesce(self._payload[self._idx['age_noted']], u'', u' (@ %s)')
    153                  if self._payload[self._idx['contributed_to_death']]:
    154                          line += u' %s %s' % (
    155                                  gmTools.u_right_arrow,
    156                                  gmTools.u_skull_and_crossbones
    157                          )
    158
    159                  if include_episode:
    160                          line += u'\n%s  %s: %s' % (
    161                                  (u' ' * left_margin),
    162                                  _('Episode'),
    163                                  self._payload[self._idx['episode']]
    164                          )
    165
    166                  if include_comment:
    167                          if self._payload[self._idx['comment']] is not None:
    168                                  line += u'\n%s  %s' % (
    169                                          (u' ' * left_margin),
    170                                          self._payload[self._idx['comment']]
    171                                  )
    172
    173                  if include_codes:
    174                          codes = self.generic_codes
    175                          if len(codes) > 0:
    176                                  line += u'\n'
    177                          for c in codes:
    178                                  line += u'%s  %s: %s (%s - %s)\n' % (
    179                                          (u' ' * left_margin),
    180                                          c['code'],
    181                                          c['term'],
    182                                          c['name_short'],
    183                                          c['version']
    184                                  )
    185                          del codes
    186
    187                  return line
    188          #--------------------------------------------------------
    189          # properties
    190          #--------------------------------------------------------
    191 -        def _get_generic_codes(self):
    192                  if len(self._payload[self._idx['pk_generic_codes']]) == 0:
    193                          return []
    194
    195                  cmd = gmCoding._SQL_get_generic_linked_codes % u'pk_generic_code IN %(pks)s'
    196                  args = {'pks': tuple(self._payload[self._idx['pk_generic_codes']])}
    197                  rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    198                  return [ gmCoding.cGenericLinkedCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]
    199
    200 -        def _set_generic_codes(self, pk_codes):
    201                  queries = []
    202                  # remove all codes
    203                  if len(self._payload[self._idx['pk_generic_codes']]) > 0:
    204                          queries.append ({
    205                                  'cmd': u'DELETE FROM clin.lnk_code2fhx WHERE fk_item = %(fhx)s AND fk_generic_code IN %(codes)s',
    206                                  'args': {
    207                                          'fhx': self._payload[self._idx['pk_family_history']],
    208                                          'codes': tuple(self._payload[self._idx['pk_generic_codes']])
    209                                  }
    210                          })
    211                  # add new codes
    212                  for pk_code in pk_codes:
    213                          queries.append ({
    214                                  'cmd': u'INSERT INTO clin.lnk_code2fhx (fk_item, fk_generic_code) VALUES (%(fhx)s, %(pk_code)s)',
    215                                  'args': {
    216                                          'fhx': self._payload[self._idx['pk_family_history']],
    217                                          'pk_code': pk_code
    218                                  }
    219                          })
    220                  if len(queries) == 0:
    221                          return
    222                  # run it all in one transaction
    223                  rows, idx = gmPG2.run_rw_queries(queries = queries)
    224                  return
    225
    226          generic_codes = property(_get_generic_codes, _set_generic_codes)
    227  #------------------------------------------------------------
    228 -def get_family_history(order_by=None, patient=None):
    229
    230          args = {}
    231          where_parts = []
    232
    233          if patient is not None:
    234                  where_parts.append(u'pk_patient = %(pat)s')
    235                  args['pat'] = patient
    236
    237          if order_by is None:
    238                  if len(where_parts) == 0:
    239                          order_by = u'true'
    240                  else:
    241                          order_by = u''
    242          else:
    243                  if len(where_parts) == 0:
    244                          order_by = u'true ORDER BY %s' % order_by
    245                  else:
    246                          order_by = u'ORDER BY %s' % order_by
    247
    248          cmd = _SQL_get_family_history % u' AND '.join(where_parts) + u' ' + order_by
    249          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    250          return [ cFamilyHistory(row = {'data': r, 'idx': idx, 'pk_field': 'pk_family_history'}) for r in rows ]
    251  #------------------------------------------------------------
    252 -def create_family_history(encounter=None, episode=None, condition=None, relation=None):
    253
    254          args = {
    255                  u'enc': encounter,
    256                  u'epi': episode,
    257                  u'cond': condition,
    258                  u'rel': relation
    259          }
    260          cmd = u"""
    261                  INSERT INTO clin.family_history (
    262                          soap_cat,
    263                          fk_encounter,
    264                          fk_episode,
    265                          narrative,
    266                          fk_relation_type
    267                  ) VALUES (
    268                          's'::text,
    269                          %(enc)s,
    270                          %(epi)s,
    271                          gm.nullify_empty_string(%(cond)s),
    272                          %(rel)s
    273                  )
    274                  RETURNING pk
    275          """
    276          rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
    277
    278          return cFamilyHistory(aPK_obj = rows[0]['pk'])
    279  #------------------------------------------------------------
    280 -def delete_family_history(pk_family_history=None):
    281          args = {'pk': pk_family_history}
    282          cmd = u"DELETE FROM clin.family_history WHERE pk = %(pk)s"
    283          gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    284          return True
    285  #============================================================
    286  # main
    287  #------------------------------------------------------------
    288  if __name__ == "__main__":
    289
    290          if len(sys.argv) < 2:
    291                  sys.exit()
    292
    293          if sys.argv[1] != 'test':
    294                  sys.exit()
    295
    296          #----------------------------------------------------
    297 -        def test_get_fhx():
    298                  print "family history:"
    299                  for fhx in get_family_history():
    300                          print fhx
    301          #----------------------------------------------------
    302          test_get_fhx()
    303
    304  #============================================================
    305