Package Gnumed :: Package wxpython :: Module gmProcedureWidgets |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gmProcedureWidgets

      1  """GNUmed procedure widgets"""
      2  #================================================================
      3  __author__ = "cfmoro1976@yahoo.es, karsten.hilbert@gmx.net"
      4  __license__ = "GPL v2 or later"
      5
      6  # stdlib
      7  import sys
      8  import logging
      9
     10
     11  # 3rd party
     12  import wx
     13
     14
     15  # GNUmed
     16  if __name__ == '__main__':
     17          sys.path.insert(0, '../../')
     18  from Gnumed.pycommon import gmI18N
     19  from Gnumed.pycommon import gmDateTime
     20  if __name__ == '__main__':
     21          gmI18N.activate_locale()
     22          gmI18N.install_domain()
     23          gmDateTime.init()
     24
     25  from Gnumed.pycommon import gmTools
     26  from Gnumed.pycommon import gmDispatcher
     27  from Gnumed.pycommon import gmMatchProvider
     28
     29  from Gnumed.business import gmEMRStructItems
     30  from Gnumed.business import gmPerson
     31
     32  from Gnumed.wxpython import gmListWidgets
     33  from Gnumed.wxpython import gmEditArea
     34  from Gnumed.wxpython import gmOrganizationWidgets
     35  from Gnumed.wxpython import gmHospitalStayWidgets
     36
     37
     38  _log = logging.getLogger('gm.ui')
     39
     40  #================================================================
     41  # performed procedure related widgets/functions
     42  #----------------------------------------------------------------
     43 -def manage_performed_procedures(parent=None):
     44
     45          pat = gmPerson.gmCurrentPatient()
     46          emr = pat.emr
     47
     48          if parent is None:
     49                  parent = wx.GetApp().GetTopWindow()
     50
     51          #-----------------------------------------
     52          def get_tooltip(procedure=None):
     53                  if procedure is None:
     54                          return None
     55                  return '\n'.join(procedure.format_maximum_information(left_margin = 1))
     56
     57          #-----------------------------------------
     58          def edit(procedure=None):
     59                  return edit_procedure(parent = parent, procedure = procedure)
     60
     61          #-----------------------------------------
     62          def delete(procedure=None):
     63                  if gmEMRStructItems.delete_performed_procedure(procedure = procedure['pk_procedure']):
     64                          return True
     65
     66                  gmDispatcher.send (
     67                          signal = 'statustext',
     68                          msg = _('Cannot delete performed procedure.'),
     69                          beep = True
     70                  )
     71                  return False
     72
     73          #-----------------------------------------
     74          def refresh(lctrl):
     75                  procs = emr.get_performed_procedures()
     76                  items = [
     77                          [
     78                                  '%s%s' % (
     79                                          p['clin_when'].strftime('%Y-%m-%d'),
     80                                          gmTools.bool2subst (
     81                                                  p['is_ongoing'],
     82                                                  _(' (ongoing)'),
     83                                                  gmTools.coalesce (
     84                                                          value2test = p['clin_end'],
     85                                                          return_instead = '',
     86                                                          template4value = ' - %s',
     87                                                          function4value = ('strftime', '%Y-%m-%d')
     88                                                  )
     89                                          )
     90                                  ),
     91                                  p['performed_procedure'],
     92                                  '%s @ %s' % (p['unit'], p['organization']),
     93                                  p['episode']
     94                          ] for p in procs
     95                  ]
     96                  lctrl.set_string_items(items = items)
     97                  lctrl.set_data(data = procs)
     98
     99          #-----------------------------------------
    100          gmListWidgets.get_choices_from_list (
    101                  parent = parent,
    102                  msg = _('\nSelect the procedure you want to edit !\n'),
    103                  caption = _('Editing performed procedures ...'),
    104                  columns = [_('When'), _('Procedure'), _('Where'), _('Episode')],
    105                  single_selection = True,
    106                  edit_callback = edit,
    107                  new_callback = edit,
    108                  delete_callback = delete,
    109                  refresh_callback = refresh,
    110                  list_tooltip_callback = get_tooltip
    111          )
    112
    113  #----------------------------------------------------------------
    114 -def edit_procedure(parent=None, procedure=None, single_entry=True):
    115          ea = cProcedureEAPnl(parent, -1)
    116          ea.data = procedure
    117          ea.mode = gmTools.coalesce(procedure, 'new', 'edit')
    118          dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
    119          dlg.SetTitle(gmTools.coalesce(procedure, _('Adding a procedure'), _('Editing a procedure')))
    120          if dlg.ShowModal() == wx.ID_OK:
    121                  dlg.DestroyLater()
    122                  return True
    123          dlg.DestroyLater()
    124          return False
    125
    126  #----------------------------------------------------------------
    127  from Gnumed.wxGladeWidgets import wxgProcedureEAPnl
    128
    129 -class cProcedureEAPnl(wxgProcedureEAPnl.wxgProcedureEAPnl, gmEditArea.cGenericEditAreaMixin):
    130
    131 -        def __init__(self, *args, **kwargs):
    132                  wxgProcedureEAPnl.wxgProcedureEAPnl.__init__(self, *args, **kwargs)
    133                  gmEditArea.cGenericEditAreaMixin.__init__(self)
    134
    135                  self.mode = 'new'
    136                  self.data = None
    137
    138                  self.__init_ui()
    139          #----------------------------------------------------------------
    140 -        def __init_ui(self):
    141                  self._PRW_hospital_stay.add_callback_on_lose_focus(callback = self._on_hospital_stay_lost_focus)
    142                  self._PRW_hospital_stay.set_context(context = 'pat', val = gmPerson.gmCurrentPatient().ID)
    143                  self._PRW_location.add_callback_on_lose_focus(callback = self._on_location_lost_focus)
    144                  self._DPRW_date.add_callback_on_lose_focus(callback = self._on_start_lost_focus)
    145                  self._DPRW_end.add_callback_on_lose_focus(callback = self._on_end_lost_focus)
    146
    147                  # procedure
    148                  mp = gmMatchProvider.cMatchProvider_SQL2 (
    149                          queries = [
    150  """
    151  select distinct on (narrative) narrative, narrative
    152  from clin.procedure
    153  where narrative %(fragment_condition)s
    154  order by narrative
    155  limit 25
    156  """                     ]
    157                  )
    158                  mp.setThresholds(2, 4, 6)
    159                  self._PRW_procedure.matcher = mp
    160
    161          #----------------------------------------------------------------
    162 -        def _on_hospital_stay_lost_focus(self):
    163                  stay = self._PRW_hospital_stay.GetData()
    164                  if stay is None:
    165                          self._PRW_hospital_stay.SetText()
    166                          self._PRW_location.Enable(True)
    167                          self._PRW_episode.Enable(True)
    168                          self._LBL_hospital_details.SetLabel('')
    169                  else:
    170                          self._PRW_location.SetText()
    171                          self._PRW_location.Enable(False)
    172                          self._PRW_episode.SetText()
    173                          self._PRW_episode.Enable(False)
    174                          self._LBL_hospital_details.SetLabel(gmEMRStructItems.cHospitalStay(aPK_obj = stay).format())
    175
    176          #----------------------------------------------------------------
    177 -        def _on_location_lost_focus(self):
    178                  loc = self._PRW_location.GetData()
    179                  if loc is None:
    180                          self._PRW_hospital_stay.Enable(True)
    181                          self._PRW_episode.Enable(False)
    182                  else:
    183                          self._PRW_hospital_stay.SetText()
    184                          self._PRW_hospital_stay.Enable(False)
    185                          self._PRW_episode.Enable(True)
    186
    187          #----------------------------------------------------------------
    188 -        def _on_start_lost_focus(self):
    189                  if not self._DPRW_date.is_valid_timestamp():
    190                          return
    191                  end = self._DPRW_end.GetData()
    192                  if end is None:
    193                          return
    194                  end = end.get_pydt()
    195                  start = self._DPRW_date.GetData().get_pydt()
    196                  if start < end:
    197                          return
    198                  self._DPRW_date.display_as_valid(False)
    199
    200          #----------------------------------------------------------------
    201 -        def _on_end_lost_focus(self):
    202                  end = self._DPRW_end.GetData()
    203                  if end is None:
    204                          self._CHBOX_ongoing.Enable(True)
    205                          self._DPRW_end.display_as_valid(True)
    206                  else:
    207                          self._CHBOX_ongoing.Enable(False)
    208                          end = end.get_pydt()
    209                          now = gmDateTime.pydt_now_here()
    210                          if end > now:
    211                                  self._CHBOX_ongoing.SetValue(True)
    212                          else:
    213                                  self._CHBOX_ongoing.SetValue(False)
    214                          start = self._DPRW_date.GetData()
    215                          if start is None:
    216                                  self._DPRW_end.display_as_valid(True)
    217                          else:
    218                                  start = start.get_pydt()
    219                                  if end > start:
    220                                          self._DPRW_end.display_as_valid(True)
    221                                  else:
    222                                          self._DPRW_end.display_as_valid(False)
    223
    224          #----------------------------------------------------------------
    225          # generic Edit Area mixin API
    226          #----------------------------------------------------------------
    227 -        def _valid_for_save(self):
    228
    229                  has_errors = False
    230
    231                  if not self._DPRW_date.is_valid_timestamp():
    232                          self._DPRW_date.display_as_valid(False)
    233                          has_errors = True
    234                  else:
    235                          self._DPRW_date.display_as_valid(True)
    236
    237                  start = self._DPRW_date.GetData()
    238                  end = self._DPRW_end.GetData()
    239                  self._DPRW_end.display_as_valid(True)
    240                  if end is not None:
    241                          end = end.get_pydt()
    242                          if start is not None:
    243                                  start = start.get_pydt()
    244                                  if end < start:
    245                                          has_errors = True
    246                                          self._DPRW_end.display_as_valid(False)
    247                          if self._CHBOX_ongoing.IsChecked():
    248                                  now = gmDateTime.pydt_now_here()
    249                                  if end < now:
    250                                          has_errors = True
    251                                          self._DPRW_end.display_as_valid(False)
    252
    253                  if self._PRW_hospital_stay.GetData() is None:
    254                          if self._PRW_episode.GetValue().strip() == '':
    255                                  self._PRW_episode.display_as_valid(False)
    256                                  has_errors = True
    257                          else:
    258                                  self._PRW_episode.display_as_valid(True)
    259                  else:
    260                          self._PRW_episode.display_as_valid(True)
    261
    262                  if (self._PRW_procedure.GetValue() is None) or (self._PRW_procedure.GetValue().strip() == ''):
    263                          self._PRW_procedure.display_as_valid(False)
    264                          has_errors = True
    265                  else:
    266                          self._PRW_procedure.display_as_valid(True)
    267
    268                  invalid_location = (
    269                          (self._PRW_hospital_stay.GetData() is None) and (self._PRW_location.GetData() is None)
    270                                  or
    271                          (self._PRW_hospital_stay.GetData() is not None) and (self._PRW_location.GetData() is not None)
    272                  )
    273                  if invalid_location:
    274                          self._PRW_hospital_stay.display_as_valid(False)
    275                          self._PRW_location.display_as_valid(False)
    276                          has_errors = True
    277                  else:
    278                          self._PRW_hospital_stay.display_as_valid(True)
    279                          self._PRW_location.display_as_valid(True)
    280
    281                  if has_errors:
    282                          self.StatusText = _('Cannot save procedure.')
    283                  return (has_errors is False)
    284
    285          #----------------------------------------------------------------
    286 -        def _save_as_new(self):
    287
    288                  pat = gmPerson.gmCurrentPatient()
    289                  emr = pat.emr
    290
    291                  stay = self._PRW_hospital_stay.GetData()
    292                  if stay is None:
    293                          epi = self._PRW_episode.GetData(can_create = True)
    294                  else:
    295                          epi = gmEMRStructItems.cHospitalStay(aPK_obj = stay)['pk_episode']
    296
    297                  proc = emr.add_performed_procedure (
    298                          episode = epi,
    299                          location = self._PRW_location.GetData(),
    300                          hospital_stay = stay,
    301                          procedure = self._PRW_procedure.GetValue().strip()
    302                  )
    303
    304                  proc['clin_when'] = self._DPRW_date.GetData().get_pydt()
    305                  if self._DPRW_end.GetData() is None:
    306                          proc['clin_end'] = None
    307                  else:
    308                          proc['clin_end'] = self._DPRW_end.GetData().get_pydt()
    309                  proc['is_ongoing'] = self._CHBOX_ongoing.IsChecked()
    310                  proc['comment'] = self._TCTRL_comment.GetValue()
    311                  proc['pk_doc'] = self._PRW_document.GetData()
    312                  proc.save()
    313
    314                  proc.generic_codes = [ c['data'] for c in self._PRW_codes.GetData() ]
    315
    316                  self.data = proc
    317
    318                  return True
    319
    320          #----------------------------------------------------------------
    321 -        def _save_as_update(self):
    322                  self.data['clin_when'] = self._DPRW_date.GetData().get_pydt()
    323                  self.data['is_ongoing'] = self._CHBOX_ongoing.IsChecked()
    324                  self.data['pk_org_unit'] = self._PRW_location.GetData()
    325                  self.data['pk_hospital_stay'] = self._PRW_hospital_stay.GetData()
    326                  self.data['performed_procedure'] = self._PRW_procedure.GetValue().strip()
    327                  self.data['comment'] = self._TCTRL_comment.GetValue()
    328                  self.data['pk_doc'] = self._PRW_document.GetData()
    329                  if self._DPRW_end.GetData() is None:
    330                          self.data['clin_end'] = None
    331                  else:
    332                          self.data['clin_end'] = self._DPRW_end.GetData().get_pydt()
    333                  if self.data['pk_hospital_stay'] is None:
    334                          self.data['pk_episode'] = self._PRW_episode.GetData()
    335                  else:
    336                          self.data['pk_episode'] = gmEMRStructItems.cHospitalStay(aPK_obj = self._PRW_hospital_stay.GetData())['pk_episode']
    337                  self.data.save()
    338
    339                  self.data.generic_codes = [ c['data'] for c in self._PRW_codes.GetData() ]
    340
    341                  return True
    342
    343          #----------------------------------------------------------------
    344 -        def _refresh_as_new(self):
    345                  self._DPRW_date.SetText()
    346                  self._DPRW_end.SetText()
    347                  self._CHBOX_ongoing.SetValue(False)
    348                  self._CHBOX_ongoing.Enable(True)
    349                  self._PRW_hospital_stay.SetText()
    350                  self._LBL_hospital_details.SetLabel('')
    351                  self._PRW_location.SetText()
    352                  self._PRW_episode.SetText()
    353                  self._PRW_procedure.SetText()
    354                  self._PRW_codes.SetText()
    355                  self._PRW_document.SetText()
    356                  self._TCTRL_comment.SetValue('')
    357
    358                  self._PRW_procedure.SetFocus()
    359
    360          #----------------------------------------------------------------
    361 -        def _refresh_from_existing(self):
    362                  self._DPRW_date.SetData(data = self.data['clin_when'])
    363                  if self.data['clin_end'] is None:
    364                          self._DPRW_end.SetText()
    365                          self._CHBOX_ongoing.Enable(True)
    366                          self._CHBOX_ongoing.SetValue(self.data['is_ongoing'])
    367                  else:
    368                          self._DPRW_end.SetData(data = self.data['clin_end'])
    369                          self._CHBOX_ongoing.Enable(False)
    370                          now = gmDateTime.pydt_now_here()
    371                          if self.data['clin_end'] > now:
    372                                  self._CHBOX_ongoing.SetValue(True)
    373                          else:
    374                                  self._CHBOX_ongoing.SetValue(False)
    375                  self._PRW_episode.SetText(value = self.data['episode'], data = self.data['pk_episode'])
    376                  self._PRW_procedure.SetText(value = self.data['performed_procedure'], data = self.data['performed_procedure'])
    377                  self._PRW_document.SetData(self.data['pk_doc'])
    378                  self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], ''))
    379
    380                  if self.data['pk_hospital_stay'] is None:
    381                          self._PRW_hospital_stay.SetText()
    382                          self._PRW_hospital_stay.Enable(False)
    383                          self._LBL_hospital_details.SetLabel('')
    384                          self._PRW_location.SetText(value = '%s @ %s' % (self.data['unit'], self.data['organization']), data = self.data['pk_org_unit'])
    385                          self._PRW_location.Enable(True)
    386                          self._PRW_episode.Enable(True)
    387                  else:
    388                          self._PRW_hospital_stay.SetText(value = '%s @ %s' % (self.data['unit'], self.data['organization']), data = self.data['pk_hospital_stay'])
    389                          self._PRW_hospital_stay.Enable(True)
    390                          self._LBL_hospital_details.SetLabel(gmEMRStructItems.cHospitalStay(aPK_obj = self.data['pk_hospital_stay']).format())
    391                          self._PRW_location.SetText()
    392                          self._PRW_location.Enable(False)
    393                          self._PRW_episode.Enable(False)
    394
    395                  val, data = self._PRW_codes.generic_linked_codes2item_dict(self.data.generic_codes)
    396                  self._PRW_codes.SetText(val, data)
    397
    398                  self._PRW_procedure.SetFocus()
    399
    400          #----------------------------------------------------------------
    401 -        def _refresh_as_new_from_existing(self):
    402                  self._refresh_as_new()
    403
    404                  self._PRW_episode.SetText(value = self.data['episode'], data = self.data['pk_episode'])
    405
    406                  if self.data['pk_hospital_stay'] is None:
    407                          self._PRW_hospital_stay.SetText()
    408                          self._PRW_hospital_stay.Enable(False)
    409                          self._LBL_hospital_details.SetLabel('')
    410                          self._PRW_location.SetText(value = '%s @ %s' % (self.data['unit'], self.data['organization']), data = self.data['pk_org_unit'])
    411                          self._PRW_location.Enable(True)
    412                          self._PRW_episode.Enable(True)
    413                  else:
    414                          self._PRW_hospital_stay.SetText(value = '%s @ %s' % (self.data['unit'], self.data['organization']), data = self.data['pk_hospital_stay'])
    415                          self._PRW_hospital_stay.Enable(True)
    416                          self._LBL_hospital_details.SetLabel(gmEMRStructItems.cHospitalStay(aPK_obj = self.data['pk_hospital_stay']).format())
    417                          self._PRW_location.SetText()
    418                          self._PRW_location.Enable(False)
    419                          self._PRW_episode.Enable(False)
    420
    421                  self._PRW_procedure.SetFocus()
    422
    423          #----------------------------------------------------------------
    424          # event handlers
    425          #----------------------------------------------------------------
    426 -        def _on_add_hospital_stay_button_pressed(self, evt):
    427                  # FIXME: this would benefit from setting the created stay
    428                  gmHospitalStayWidgets.edit_hospital_stay(parent = self.GetParent())
    429                  evt.Skip()
    430
    431          #----------------------------------------------------------------
    432 -        def _on_add_location_button_pressed(self, event):
    433                  gmOrganizationWidgets.manage_orgs(parent = self)        #self.GetParent())
    434                  event.Skip()
    435
    436          #----------------------------------------------------------------
    437 -        def _on_ongoing_checkbox_checked(self, event):
    438                  if self._CHBOX_ongoing.IsChecked():
    439                          end = self._DPRW_end.GetData()
    440                          if end is None:
    441                                  self._DPRW_end.display_as_valid(True)
    442                          else:
    443                                  end = end.get_pydt()
    444                                  now = gmDateTime.pydt_now_here()
    445                                  if end > now:
    446                                          self._DPRW_end.display_as_valid(True)
    447                                  else:
    448                                          self._DPRW_end.display_as_valid(False)
    449                  else:
    450                          self._DPRW_end.is_valid_timestamp()
    451                  event.Skip()
    452
    453
    454  #================================================================
    455  # main
    456  #----------------------------------------------------------------
    457  if __name__ == '__main__':
    458
    459          if len(sys.argv) < 2:
    460                  sys.exit()
    461
    462          if sys.argv[1] != 'test':
    463                  sys.exit()
    464
    465          from Gnumed.business import gmPersonSearch
    466          from Gnumed.wxpython import gmPatSearchWidgets
    467
    468          #----------------------------------------------------------------
    469 -        def test_edit_procedure():
    470                  app = wx.PyWidgetTester(size = (200, 300))
    471                  edit_procedure(parent=app.frame)
    472
    473          #================================================================
    474          # obtain patient
    475          pat = gmPersonSearch.ask_for_patient()
    476          if pat is None:
    477                  print("No patient. Exiting gracefully...")
    478                  sys.exit(0)
    479          gmPatSearchWidgets.set_active_patient(patient=pat)
    480
    481  #       try:
    482                  # lauch emr dialogs test application
    483  #               app = testapp(0)
    484  #               app.MainLoop()
    485  #       except Exception:
    486  #               _log.exception("unhandled exception caught !")
    487                  # but re-raise them
    488  #               raise
    489
    490          test_edit_procedure()
    491