Gnumed.wxpython.gmNarrativeWorkflows

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

# Source Code for Module Gnumed.wxpython.gmNarrativeWorkflows

      1  """GNUmed narrative workflows."""
      2  #================================================================
      3  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
      4  __license__ = "GPL v2 or later (details at http://www.gnu.org)"
      5
      6  import sys
      7  import logging
      8  import os.path
      9  import time
     10
     11
     12  import wx
     13
     14
     15  if __name__ == '__main__':
     16          sys.path.insert(0, '../../')
     17
     18  from Gnumed.pycommon import gmI18N
     19
     20  if __name__ == '__main__':
     21          gmI18N.activate_locale()
     22          gmI18N.install_domain()
     23
     24  from Gnumed.pycommon import gmDispatcher
     25  from Gnumed.pycommon import gmTools
     26  from Gnumed.pycommon import gmDateTime
     27
     28  from Gnumed.business import gmPerson
     29  from Gnumed.business import gmStaff
     30  from Gnumed.business import gmEMRStructItems
     31  from Gnumed.business import gmClinNarrative
     32  from Gnumed.business import gmSoapDefs
     33
     34  from Gnumed.wxpython import gmListWidgets
     35  from Gnumed.wxpython import gmEMRStructWidgets
     36  from Gnumed.wxpython import gmEncounterWidgets
     37  from Gnumed.wxpython import gmGuiHelpers
     38  from Gnumed.wxpython import gmNarrativeWidgets
     39  from Gnumed.wxpython.gmPatSearchWidgets import set_active_patient
     40
     41  from Gnumed.exporters import gmPatientExporter
     42
     43
     44  _log = logging.getLogger('gm.ui')
     45  #============================================================
     46  # narrative related widgets/functions
     47  #------------------------------------------------------------
     48 -def move_progress_notes_to_another_encounter(parent=None, encounters=None, episodes=None, patient=None, move_all=False):
     49
     50          # sanity checks
     51          if patient is None:
     52                  patient = gmPerson.gmCurrentPatient()
     53
     54          if not patient.connected:
     55                  gmDispatcher.send(signal = 'statustext', msg = _('Cannot move progress notes. No active patient.'))
     56                  return False
     57
     58          if parent is None:
     59                  parent = wx.GetApp().GetTopWindow()
     60
     61          emr = patient.emr
     62
     63          if encounters is None:
     64                  all_encs_in_epi = emr.get_encounters(episodes = episodes, skip_empty = True)
     65                  # nothing to do ?
     66                  if len(all_encs_in_epi) == 0:
     67                          return True
     68                  encounters = gmEncounterWidgets.select_encounters (
     69                          parent = parent,
     70                          patient = patient,
     71                          single_selection = False,
     72                          encounters = all_encs_in_epi
     73                  )
     74                  # cancelled
     75                  if encounters is None:
     76                          return True
     77                  # none selected
     78                  if len(encounters) == 0:
     79                          return True
     80
     81          notes = emr.get_clin_narrative (
     82                  encounters = encounters,
     83                  episodes = episodes
     84          )
     85
     86          # which narrative
     87          if move_all:
     88                  selected_narr = notes
     89          else:
     90                  selected_narr = gmListWidgets.get_choices_from_list (
     91                          parent = parent,
     92                          caption = _('Moving progress notes between encounters ...'),
     93                          single_selection = False,
     94                          can_return_empty = True,
     95                          data = notes,
     96                          msg = _('\n Select the progress notes to move from the list !\n\n'),
     97                          columns = [_('when'), _('who'), _('type'), _('entry')],
     98                          choices = [
     99                                  [       narr['date'].strftime('%x %H:%M'),
    100                                          narr['modified_by'],
    101                                          gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
    102                                          narr['narrative'].replace('\n', '/').replace('\r', '/')
    103                                  ] for narr in notes
    104                          ]
    105                  )
    106
    107          if not selected_narr:
    108                  return True
    109
    110          # which encounter to move to
    111          enc2move2 = gmEncounterWidgets.select_encounters (
    112                  parent = parent,
    113                  patient = patient,
    114                  single_selection = True
    115          )
    116
    117          if not enc2move2:
    118                  return True
    119
    120          for narr in selected_narr:
    121                  narr['pk_encounter'] = enc2move2['pk_encounter']
    122                  narr.save()
    123
    124          return True
    125
    126  #------------------------------------------------------------
    127 -def manage_progress_notes(parent=None, encounters=None, episodes=None, patient=None):
    128
    129          # sanity checks
    130          if patient is None:
    131                  patient = gmPerson.gmCurrentPatient()
    132
    133          if not patient.connected:
    134                  gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit progress notes. No active patient.'))
    135                  return False
    136
    137          if parent is None:
    138                  parent = wx.GetApp().GetTopWindow()
    139
    140          emr = patient.emr
    141          #--------------------------
    142          def delete(item):
    143                  if item is None:
    144                          return False
    145                  dlg = gmGuiHelpers.c2ButtonQuestionDlg (
    146                          parent,
    147                          -1,
    148                          caption = _('Deleting progress note'),
    149                          question = _(
    150                                  'Are you positively sure you want to delete this\n'
    151                                  'progress note from the medical record ?\n'
    152                                  '\n'
    153                                  'Note that even if you chose to delete the entry it will\n'
    154                                  'still be (invisibly) kept in the audit trail to protect\n'
    155                                  'you from litigation because physical deletion is known\n'
    156                                  'to be unlawful in some jurisdictions.\n'
    157                          ),
    158                          button_defs = (
    159                                  {'label': _('Delete'), 'tooltip': _('Yes, delete the progress note.'), 'default': False},
    160                                  {'label': _('Cancel'), 'tooltip': _('No, do NOT delete the progress note.'), 'default': True}
    161                          )
    162                  )
    163                  decision = dlg.ShowModal()
    164
    165                  if decision != wx.ID_YES:
    166                          return False
    167
    168                  gmClinNarrative.delete_clin_narrative(narrative = item['pk_narrative'])
    169                  return True
    170          #--------------------------
    171          def edit(item):
    172                  if item is None:
    173                          return False
    174
    175                  dlg = gmGuiHelpers.cMultilineTextEntryDlg (
    176                          parent,
    177                          -1,
    178                          title = _('Editing progress note'),
    179                          msg = _('This is the original progress note:'),
    180                          data = item.format(left_margin = ' ', fancy = True),
    181                          text = item['narrative']
    182                  )
    183                  decision = dlg.ShowModal()
    184
    185                  if decision != wx.ID_SAVE:
    186                          return False
    187
    188                  val = dlg.value
    189                  dlg.Destroy()
    190                  if val.strip() == '':
    191                          return False
    192
    193                  item['narrative'] = val
    194                  item.save_payload()
    195
    196                  return True
    197          #--------------------------
    198          def refresh(lctrl):
    199                  notes = emr.get_clin_narrative (
    200                          encounters = encounters,
    201                          episodes = episodes,
    202                          providers = [ gmStaff.gmCurrentProvider()['short_alias'] ]
    203                  )
    204                  lctrl.set_string_items(items = [
    205                          [       narr['date'].strftime('%x %H:%M'),
    206                                  gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
    207                                  narr['narrative'].replace('\n', '/').replace('\r', '/')
    208                          ] for narr in notes
    209                  ])
    210                  lctrl.set_data(data = notes)
    211          #--------------------------
    212
    213          gmListWidgets.get_choices_from_list (
    214                  parent = parent,
    215                  caption = _('Managing progress notes'),
    216                  msg = _(
    217                          '\n'
    218                          ' This list shows the progress notes by %s.\n'
    219                          '\n'
    220                  ) % gmStaff.gmCurrentProvider()['short_alias'],
    221                  columns = [_('when'), _('type'), _('entry')],
    222                  single_selection = True,
    223                  can_return_empty = False,
    224                  edit_callback = edit,
    225                  delete_callback = delete,
    226                  refresh_callback = refresh
    227          )
    228
    229  #------------------------------------------------------------
    230 -def search_narrative_across_emrs(parent=None):
    231
    232          if parent is None:
    233                  parent = wx.GetApp().GetTopWindow()
    234
    235          search_term_dlg = wx.TextEntryDialog (
    236                  parent = parent,
    237                  message = _('Enter (regex) term to search for across all EMRs:'),
    238                  caption = _('Text search across all EMRs'),
    239                  style = wx.OK | wx.CANCEL | wx.CENTRE
    240          )
    241          result = search_term_dlg.ShowModal()
    242
    243          if result != wx.ID_OK:
    244                  return
    245
    246          wx.BeginBusyCursor()
    247          search_term = search_term_dlg.GetValue()
    248          search_term_dlg.Destroy()
    249          results = gmClinNarrative.search_text_across_emrs(search_term = search_term)
    250          wx.EndBusyCursor()
    251
    252          if len(results) == 0:
    253                  gmGuiHelpers.gm_show_info (
    254                          _(
    255                          'Nothing found for search term:\n'
    256                          ' "%s"'
    257                          ) % search_term,
    258                          _('Search results')
    259                  )
    260                  return
    261
    262          items = [ [
    263                  gmPerson.cPerson(aPK_obj = r['pk_patient'])['description_gender'],
    264                  r['narrative'],
    265                  r['src_table']
    266          ] for r in results ]
    267
    268          selected_patient = gmListWidgets.get_choices_from_list (
    269                  parent = parent,
    270                  caption = _('Search results for [%s]') % search_term,
    271                  choices = items,
    272                  columns = [_('Patient'), _('Match'), _('Match location')],
    273                  data = [ r['pk_patient'] for r in results ],
    274                  single_selection = True,
    275                  can_return_empty = False
    276          )
    277
    278          if selected_patient is None:
    279                  return
    280
    281          wx.CallAfter(set_active_patient, patient = gmPerson.cPerson(aPK_obj = selected_patient))
    282
    283  #------------------------------------------------------------
    284 -def search_narrative_in_emr(parent=None, patient=None):
    285
    286          # sanity checks
    287          if patient is None:
    288                  patient = gmPerson.gmCurrentPatient()
    289
    290          if not patient.connected:
    291                  gmDispatcher.send(signal = 'statustext', msg = _('Cannot search EMR. No active patient.'))
    292                  return False
    293
    294          if parent is None:
    295                  parent = wx.GetApp().GetTopWindow()
    296
    297          search_term_dlg = wx.TextEntryDialog (
    298                  parent = parent,
    299                  message = _('Enter search term:'),
    300                  caption = _('Text search of entire EMR of active patient'),
    301                  style = wx.OK | wx.CANCEL | wx.CENTRE
    302          )
    303          result = search_term_dlg.ShowModal()
    304
    305          if result != wx.ID_OK:
    306                  search_term_dlg.Destroy()
    307                  return False
    308
    309          wx.BeginBusyCursor()
    310          val = search_term_dlg.GetValue()
    311          search_term_dlg.Destroy()
    312          emr = patient.emr
    313          rows = emr.search_narrative_simple(val)
    314          wx.EndBusyCursor()
    315
    316          if len(rows) == 0:
    317                  gmGuiHelpers.gm_show_info (
    318                          _(
    319                          'Nothing found for search term:\n'
    320                          ' "%s"'
    321                          ) % val,
    322                          _('Search results')
    323                  )
    324                  return True
    325
    326          txt = ''
    327          for row in rows:
    328                  txt += '%s: %s\n' % (
    329                          row['soap_cat'],
    330                          row['narrative']
    331                  )
    332
    333                  txt += ' %s: %s - %s %s\n' % (
    334                          _('Encounter'),
    335                          row['encounter_started'].strftime('%x %H:%M'),
    336                          row['encounter_ended'].strftime('%H:%M'),
    337                          row['encounter_type']
    338                  )
    339                  txt += ' %s: %s\n' % (
    340                          _('Episode'),
    341                          row['episode']
    342                  )
    343                  txt += ' %s: %s\n\n' % (
    344                          _('Health issue'),
    345                          row['health_issue']
    346                  )
    347
    348          msg = _(
    349                  'Search term was: "%s"\n'
    350                  '\n'
    351                  'Search results:\n\n'
    352                  '%s\n'
    353          ) % (val, txt)
    354
    355          dlg = wx.MessageDialog (
    356                  parent = parent,
    357                  message = msg,
    358                  caption = _('Search results for [%s]') % val,
    359                  style = wx.OK | wx.STAY_ON_TOP
    360          )
    361          dlg.ShowModal()
    362          dlg.Destroy()
    363
    364          return True
    365
    366  #------------------------------------------------------------
    367 -def export_narrative_for_medistar_import(parent=None, soap_cats='soapu', encounter=None):
    368
    369          # sanity checks
    370          pat = gmPerson.gmCurrentPatient()
    371          if not pat.connected:
    372                  gmDispatcher.send(signal = 'statustext', msg = _('Cannot export EMR for Medistar. No active patient.'))
    373                  return False
    374
    375          if encounter is None:
    376                  encounter = pat.emr.active_encounter
    377
    378          if parent is None:
    379                  parent = wx.GetApp().GetTopWindow()
    380
    381          # get file name
    382          aWildcard = "%s (*.txt)|*.txt|%s (*)|*" % (_("text files"), _("all files"))
    383                  # FIXME: make configurable
    384          aDefDir = os.path.abspath(os.path.expanduser(os.path.join('~', 'gnumed')))
    385                  # FIXME: make configurable
    386          fname = '%s-%s-%s-%s-%s.txt' % (
    387                  'Medistar-MD',
    388                  time.strftime('%Y-%m-%d',time.localtime()),
    389                  pat['lastnames'].replace(' ', '-'),
    390                  pat['firstnames'].replace(' ', '_'),
    391                  pat.get_formatted_dob(format = '%Y-%m-%d')
    392          )
    393          dlg = wx.FileDialog (
    394                  parent = parent,
    395                  message = _("Save EMR extract for MEDISTAR import as..."),
    396                  defaultDir = aDefDir,
    397                  defaultFile = fname,
    398                  wildcard = aWildcard,
    399                  style = wx.FD_SAVE
    400          )
    401          choice = dlg.ShowModal()
    402          fname = dlg.GetPath()
    403          dlg.Destroy()
    404          if choice != wx.ID_OK:
    405                  return False
    406
    407          wx.BeginBusyCursor()
    408          _log.debug('exporting encounter for medistar import to [%s]', fname)
    409          exporter = gmPatientExporter.cMedistarSOAPExporter(patient = pat)
    410          successful, fname = exporter.save_to_file (
    411                  filename = fname,
    412                  encounter = encounter,
    413                  soap_cats = 'soapu',
    414                  export_to_import_file = True
    415          )
    416          if not successful:
    417                  gmGuiHelpers.gm_show_error (
    418                          _('Error exporting progress notes for MEDISTAR import.'),
    419                          _('MEDISTAR progress notes export')
    420                  )
    421                  wx.EndBusyCursor()
    422                  return False
    423
    424          gmDispatcher.send(signal = 'statustext', msg = _('Successfully exported progress notes into file [%s] for Medistar import.') % fname, beep=False)
    425
    426          wx.EndBusyCursor()
    427          return True
    428
    429  #------------------------------------------------------------
    430 -def select_narrative(parent=None, soap_cats=None, msg=None):
    431
    432          pat = gmPerson.gmCurrentPatient()
    433          emr = pat.emr
    434
    435          if parent is None:
    436                  parent = wx.GetApp().GetTopWindow()
    437
    438          if soap_cats is None:
    439                  soap_cats = 'soapu'
    440          soap_cats = list(soap_cats)
    441          i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
    442
    443          if msg is None:
    444                  msg = _('Pick the [%s] narrative you want to use.') % '/'.join(i18n_soap_cats)
    445
    446          #-----------------------------------------------
    447          def get_tooltip(soap):
    448                  return soap.format(fancy = True, width = 60)
    449          #-----------------------------------------------
    450          def refresh(lctrl):
    451                  lctrl.secondary_sort_column = 0
    452                  soap = emr.get_clin_narrative(soap_cats = soap_cats)
    453                  lctrl.set_string_items ([ [
    454                          gmDateTime.pydt_strftime(s['date'], '%Y %m %d'),
    455                          s['modified_by'],
    456                          gmSoapDefs.soap_cat2l10n[s['soap_cat']],
    457                          s['narrative'],
    458                          s['episode'],
    459                          s['health_issue']
    460                  ] for s in soap ])
    461                  lctrl.set_data(soap)
    462          #-----------------------------------------------
    463          return gmListWidgets.get_choices_from_list (
    464                  parent = parent,
    465                  msg = msg,
    466                  caption = _('Picking [%s] narrative') % ('/'.join(i18n_soap_cats)),
    467                  columns = [_('When'), _('Who'), _('Type'), _('Entry'), _('Episode'), _('Issue')],
    468                  single_selection = False,
    469                  can_return_empty = False,
    470                  refresh_callback = refresh,
    471                  list_tooltip_callback = get_tooltip
    472          )
    473
    474  #------------------------------------------------------------
    475 -def select_narrative_by_issue(parent=None, soap_cats=None):
    476
    477          pat = gmPerson.gmCurrentPatient()
    478          emr = pat.emr
    479
    480          # not useful if you think about it:
    481  #       issues = [ i for i in emr.health_issues ]
    482  #       if len(issues) == 0:
    483  #               gmDispatcher.send(signal = 'statustext', msg = _('No progress notes found.'))
    484  #               return []
    485
    486          if parent is None:
    487                  parent = wx.GetApp().GetTopWindow()
    488
    489          if soap_cats is None:
    490                  soap_cats = 'soapu'
    491          soap_cats = list(soap_cats)
    492          i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
    493
    494          selected_soap = {}
    495          #selected_narrative_pks = []
    496
    497          #-----------------------------------------------
    498          def get_soap_tooltip(soap):
    499                  return soap.format(fancy = True, width = 60)
    500          #-----------------------------------------------
    501          def pick_soap_from_issue(issue):
    502
    503                  if issue is None:
    504                          return False
    505
    506                  narr_for_issue = emr.get_clin_narrative(issues = [issue['pk_health_issue']], soap_cats = soap_cats)
    507
    508                  if len(narr_for_issue) == 0:
    509                          gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for this health issue.'))
    510                          return True
    511
    512                  selected_narr = gmListWidgets.get_choices_from_list (
    513                          parent = parent,
    514                          msg = _('Pick the [%s] narrative you want to include in the report.') % '/'.join(i18n_soap_cats),
    515                          caption = _('Picking [%s] from %s%s%s') % (
    516                                  '/'.join(i18n_soap_cats),
    517                                  gmTools.u_left_double_angle_quote,
    518                                  issue['description'],
    519                                  gmTools.u_right_double_angle_quote
    520                          ),
    521                          columns = [_('When'), _('Who'), _('Type'), _('Entry')],
    522                          choices = [ [
    523                                  gmDateTime.pydt_strftime(narr['date'], '%Y %b %d  %H:%M', accuracy = gmDateTime.acc_minutes),
    524                                  narr['modified_by'],
    525                                  gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
    526                                  narr['narrative'].replace('\n', '//').replace('\r', '//')
    527                          ] for narr in narr_for_issue ],
    528                          data = narr_for_issue,
    529                          #selections=None,
    530                          #edit_callback=None,
    531                          single_selection = False,
    532                          can_return_empty = False,
    533                          list_tooltip_callback = get_soap_tooltip
    534                  )
    535
    536                  if selected_narr is None:
    537                          return True
    538
    539                  for narr in selected_narr:
    540                          selected_soap[narr['pk_narrative']] = narr
    541
    542                  return True
    543          #-----------------------------------------------
    544          def edit_issue(issue):
    545                  return gmEMRStructWidgets.edit_health_issue(parent = parent, issue = issue)
    546          #-----------------------------------------------
    547          def refresh_issues(lctrl):
    548                  #issues = [ i for i in emr.health_issues ]
    549                  issues = emr.health_issues
    550                  lctrl.set_string_items ([ [
    551                                  gmTools.bool2subst(i['is_confidential'], _('!! CONFIDENTIAL !!'), ''),
    552                                  i['description'],
    553                                  gmTools.bool2subst(i['is_active'], _('active'), _('inactive'))
    554                          ] for i in issues
    555                  ])
    556                  lctrl.set_data(issues)
    557          #-----------------------------------------------
    558          def get_issue_tooltip(issue):
    559                  return issue.format (
    560                          patient = pat,
    561                          with_encounters = False,
    562                          with_medications = False,
    563                          with_hospital_stays = False,
    564                          with_procedures = False,
    565                          with_family_history = False,
    566                          with_documents = False,
    567                          with_tests = False,
    568                          with_vaccinations = False
    569                  )
    570          #-----------------------------------------------
    571          #selected_episode_pks = []
    572
    573          issues_picked_from = gmListWidgets.get_choices_from_list (
    574                  parent = parent,
    575                  msg = _('\n Select the issue you want to report on.'),
    576                  caption = _('Picking [%s] from health issues') % '/'.join(i18n_soap_cats),
    577                  columns = [_('Privacy'), _('Issue'), _('Status')],
    578                  edit_callback = edit_issue,
    579                  refresh_callback = refresh_issues,
    580                  single_selection = True,
    581                  can_return_empty = True,
    582                  ignore_OK_button = False,
    583                  left_extra_button = (
    584                          _('&Pick notes'),
    585                          _('Pick [%s] entries from selected health issue') % '/'.join(i18n_soap_cats),
    586                          pick_soap_from_issue
    587                  ),
    588                  list_tooltip_callback = get_issue_tooltip
    589          )
    590
    591          if issues_picked_from is None:
    592                  return []
    593
    594          return selected_soap.values()
    595
    596  #       selection_idxs = []
    597  #       for idx in range(len(all_epis)):
    598  #               if all_epis[idx]['pk_episode'] in selected_episode_pks:
    599  #                       selection_idxs.append(idx)
    600  #       if len(selection_idxs) != 0:
    601  #               dlg.set_selections(selections = selection_idxs)
    602
    603  #------------------------------------------------------------
    604 -def select_narrative_by_episode(parent=None, soap_cats=None):
    605
    606          pat = gmPerson.gmCurrentPatient()
    607          emr = pat.emr
    608
    609          all_epis = [ epi for epi in emr.get_episodes(order_by = 'description') if epi.has_narrative ]
    610          if len(all_epis) == 0:
    611                  gmDispatcher.send(signal = 'statustext', msg = _('No episodes with progress notes found.'))
    612                  return []
    613
    614          if parent is None:
    615                  parent = wx.GetApp().GetTopWindow()
    616
    617          if soap_cats is None:
    618                  soap_cats = 'soapu'
    619          soap_cats = list(soap_cats)
    620          i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
    621
    622          selected_soap = {}
    623          #selected_narrative_pks = []
    624
    625          #-----------------------------------------------
    626          def get_soap_tooltip(soap):
    627                  return soap.format(fancy = True, width = 60)
    628          #-----------------------------------------------
    629          def pick_soap_from_episode(episode):
    630
    631                  if episode is None:
    632                          return False
    633
    634                  narr_for_epi = emr.get_clin_narrative(episodes = [episode['pk_episode']], soap_cats = soap_cats)
    635
    636                  if len(narr_for_epi) == 0:
    637                          gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for selected episode.'))
    638                          return True
    639
    640                  selected_narr = gmListWidgets.get_choices_from_list (
    641                          parent = parent,
    642                          msg = _('Pick the [%s] narrative you want to include in the report.') % '/'.join(i18n_soap_cats),
    643                          caption = _('Picking [%s] from %s%s%s') % (
    644                                  '/'.join(i18n_soap_cats),
    645                                  gmTools.u_left_double_angle_quote,
    646                                  episode['description'],
    647                                  gmTools.u_right_double_angle_quote
    648                          ),
    649                          columns = [_('When'), _('Who'), _('Type'), _('Entry')],
    650                          choices = [ [
    651                                  gmDateTime.pydt_strftime(narr['date'], '%Y %b %d  %H:%M', accuracy = gmDateTime.acc_minutes),
    652                                  narr['modified_by'],
    653                                  gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
    654                                  narr['narrative'].replace('\n', '//').replace('\r', '//')
    655                          ] for narr in narr_for_epi ],
    656                          data = narr_for_epi,
    657                          #selections=None,
    658                          #edit_callback=None,
    659                          single_selection = False,
    660                          can_return_empty = False,
    661                          list_tooltip_callback = get_soap_tooltip
    662                  )
    663
    664                  if selected_narr is None:
    665                          return True
    666
    667                  for narr in selected_narr:
    668                          selected_soap[narr['pk_narrative']] = narr
    669
    670                  return True
    671
    672  #               selection_idxs = []
    673  #               for idx in range(len(narr_for_epi)):
    674  #                       if narr_for_epi[idx]['pk_narrative'] in selected_narrative_pks:
    675  #                               selection_idxs.append(idx)
    676  #               if len(selection_idxs) != 0:
    677  #                       dlg.set_selections(selections = selection_idxs)
    678
    679  #               selected_narrative_pks = [ i['pk_narrative'] for i in selected_narr ]
    680  #               for narr in selected_narr:
    681  #                       selected_soap[narr['pk_narrative']] = narr
    682  #
    683  #               print "before returning from picking soap"
    684  #
    685  #               return True
    686  #       #-----------------------------------------------
    687          def edit_episode(episode):
    688                  return gmEMRStructWidgets.edit_episode(parent = parent, episode = episode)
    689          #-----------------------------------------------
    690          def refresh_episodes(lctrl):
    691                  all_epis = [ epi for epi in emr.get_episodes(order_by = 'description') if epi.has_narrative ]
    692                  lctrl.set_string_items ([ [
    693                                  '%s%s' % (e['description'], gmTools.coalesce(e['health_issue'], '', ' (%s)')),
    694                                  gmTools.bool2subst(e['episode_open'], _('open'), _('closed'))
    695                          ] for e in all_epis
    696                  ])
    697                  lctrl.set_data(all_epis)
    698          #-----------------------------------------------
    699          def get_episode_tooltip(episode):
    700                  return episode.format (
    701                          patient = pat,
    702                          with_encounters = False,
    703                          with_documents = False,
    704                          with_hospital_stays = False,
    705                          with_procedures = False,
    706                          with_family_history = False,
    707                          with_tests = False,
    708                          with_vaccinations = False
    709                  )
    710          #-----------------------------------------------
    711          #selected_episode_pks = []
    712
    713          epis_picked_from = gmListWidgets.get_choices_from_list (
    714                  parent = parent,
    715                  msg = _('\n Select the episode you want to report on.'),
    716                  caption = _('Picking [%s] from episodes') % '/'.join(i18n_soap_cats),
    717                  columns = [_('Episode'), _('Status')],
    718                  edit_callback = edit_episode,
    719                  refresh_callback = refresh_episodes,
    720                  single_selection = True,
    721                  can_return_empty = True,
    722                  ignore_OK_button = False,
    723                  left_extra_button = (
    724                          _('&Pick notes'),
    725                          _('Pick [%s] entries from selected episode') % '/'.join(i18n_soap_cats),
    726                          pick_soap_from_episode
    727                  ),
    728                  list_tooltip_callback = get_episode_tooltip
    729          )
    730
    731          if epis_picked_from is None:
    732                  return []
    733
    734          return selected_soap.values()
    735
    736  #       selection_idxs = []
    737  #       for idx in range(len(all_epis)):
    738  #               if all_epis[idx]['pk_episode'] in selected_episode_pks:
    739  #                       selection_idxs.append(idx)
    740  #       if len(selection_idxs) != 0:
    741  #               dlg.set_selections(selections = selection_idxs)
    742
    743  #------------------------------------------------------------
    744 -def select_narrative_from_episodes(parent=None, soap_cats=None):
    745          """soap_cats needs to be a list"""
    746
    747          pat = gmPerson.gmCurrentPatient()
    748          emr = pat.emr
    749
    750          if parent is None:
    751                  parent = wx.GetApp().GetTopWindow()
    752
    753          selected_soap = {}
    754          selected_issue_pks = []
    755          selected_episode_pks = []
    756          selected_narrative_pks = []
    757
    758          while 1:
    759                  # 1) select health issues to select episodes from
    760                  all_issues = emr.get_health_issues()
    761                  all_issues.insert(0, gmEMRStructItems.get_dummy_health_issue())
    762                  dlg = gmEMRStructWidgets.cIssueListSelectorDlg (
    763                          parent = parent,
    764                          id = -1,
    765                          issues = all_issues,
    766                          msg = _('\n In the list below mark the health issues you want to report on.\n')
    767                  )
    768                  selection_idxs = []
    769                  for idx in range(len(all_issues)):
    770                          if all_issues[idx]['pk_health_issue'] in selected_issue_pks:
    771                                  selection_idxs.append(idx)
    772                  if len(selection_idxs) != 0:
    773                          dlg.set_selections(selections = selection_idxs)
    774                  btn_pressed = dlg.ShowModal()
    775                  selected_issues = dlg.get_selected_item_data()
    776                  dlg.Destroy()
    777
    778                  if btn_pressed == wx.ID_CANCEL:
    779                          return selected_soap.values()
    780
    781                  selected_issue_pks = [ i['pk_health_issue'] for i in selected_issues ]
    782
    783                  while 1:
    784                          # 2) select episodes to select items from
    785                          all_epis = emr.get_episodes(issues = selected_issue_pks)
    786
    787                          if len(all_epis) == 0:
    788                                  gmDispatcher.send(signal = 'statustext', msg = _('No episodes recorded for the health issues selected.'))
    789                                  break
    790
    791                          dlg = gmEMRStructWidgets.cEpisodeListSelectorDlg (
    792                                  parent = parent,
    793                                  id = -1,
    794                                  episodes = all_epis,
    795                                  msg = _(
    796                                          '\n These are the episodes known for the health issues just selected.\n\n'
    797                                          ' Now, mark the the episodes you want to report on.\n'
    798                                  )
    799                          )
    800                          selection_idxs = []
    801                          for idx in range(len(all_epis)):
    802                                  if all_epis[idx]['pk_episode'] in selected_episode_pks:
    803                                          selection_idxs.append(idx)
    804                          if len(selection_idxs) != 0:
    805                                  dlg.set_selections(selections = selection_idxs)
    806                          btn_pressed = dlg.ShowModal()
    807                          selected_epis = dlg.get_selected_item_data()
    808                          dlg.Destroy()
    809
    810                          if btn_pressed == wx.ID_CANCEL:
    811                                  break
    812
    813                          selected_episode_pks = [ i['pk_episode'] for i in selected_epis ]
    814
    815                          # 3) select narrative corresponding to the above constraints
    816                          all_narr = emr.get_clin_narrative(episodes = selected_episode_pks, soap_cats = soap_cats)
    817
    818                          if len(all_narr) == 0:
    819                                  gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for selected episodes.'))
    820                                  continue
    821
    822                          dlg = cNarrativeListSelectorDlg (
    823                                  parent = parent,
    824                                  id = -1,
    825                                  narrative = all_narr,
    826                                  msg = _(
    827                                          '\n This is the narrative (type %s) for the chosen episodes.\n\n'
    828                                          ' Now, mark the entries you want to include in your report.\n'
    829                                  ) % '/'.join([ gmSoapDefs.soap_cat2l10n[cat] for cat in gmTools.coalesce(soap_cats, list('soapu')) ])
    830                          )
    831                          selection_idxs = []
    832                          for idx in range(len(all_narr)):
    833                                  if all_narr[idx]['pk_narrative'] in selected_narrative_pks:
    834                                          selection_idxs.append(idx)
    835                          if len(selection_idxs) != 0:
    836                                  dlg.set_selections(selections = selection_idxs)
    837                          btn_pressed = dlg.ShowModal()
    838                          selected_narr = dlg.get_selected_item_data()
    839                          dlg.Destroy()
    840
    841                          if btn_pressed == wx.ID_CANCEL:
    842                                  continue
    843
    844                          selected_narrative_pks = [ i['pk_narrative'] for i in selected_narr ]
    845                          for narr in selected_narr:
    846                                  selected_soap[narr['pk_narrative']] = narr
    847
    848  #============================================================
    849  # main
    850  #------------------------------------------------------------
    851  if __name__ == '__main__':
    852
    853          if len(sys.argv) < 2:
    854                  sys.exit()
    855
    856          if sys.argv[1] != 'test':
    857                  sys.exit()
    858
    859          from Gnumed.business import gmPersonSearch
    860
    861          gmI18N.activate_locale()
    862          gmI18N.install_domain(domain = 'gnumed')
    863
    864          #----------------------------------------
    865 -        def test_select_narrative_from_episodes():
    866                  pat = gmPersonSearch.ask_for_patient()
    867                  set_active_patient(patient = pat)
    868                  app = wx.PyWidgetTester(size = (200, 200))
    869                  sels = select_narrative_from_episodes_new()
    870                  print("selected:")
    871                  for sel in sels:
    872                          print(sel)
    873          #----------------------------------------
    874 -        def test_select_narrative():
    875                  pat = gmPersonSearch.ask_for_patient()
    876                  set_active_patient(patient = pat)
    877                  app = wx.PyWidgetTester(size = (200, 200))
    878                  sels = select_narrative(parent=None, soap_cats = None)
    879                  print("selected:")
    880                  for sel in sels:
    881                          print(sel)
    882          #----------------------------------------
    883          #test_select_narrative_from_episodes()
    884          test_select_narrative()
    885