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

Source Code for Module Gnumed.wxpython.gmPatOverviewWidgets

   1  """GNUmed patient overview widgets. 
   2   
   3  copyright: authors 
   4  """ 
   5  #============================================================ 
   6  __author__ = "K.Hilbert" 
   7  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
   8   
   9  import logging, sys 
  10   
  11   
  12  import wx 
  13   
  14   
  15  if __name__ == '__main__': 
  16          sys.path.insert(0, '../../') 
  17  from Gnumed.pycommon import gmTools 
  18  from Gnumed.pycommon import gmDispatcher 
  19  from Gnumed.pycommon import gmDateTime 
  20  from Gnumed.pycommon import gmNetworkTools 
  21   
  22  from Gnumed.business import gmPerson 
  23  from Gnumed.business import gmStaff 
  24  from Gnumed.business import gmDemographicRecord 
  25  from Gnumed.business import gmEMRStructItems 
  26  from Gnumed.business import gmFamilyHistory 
  27  from Gnumed.business import gmVaccination 
  28  from Gnumed.business import gmDocuments 
  29  from Gnumed.business import gmProviderInbox 
  30   
  31  from Gnumed.wxpython import gmRegetMixin 
  32  from Gnumed.wxpython import gmDemographicsWidgets 
  33  from Gnumed.wxpython import gmContactWidgets 
  34  from Gnumed.wxpython import gmMedicationWidgets 
  35  from Gnumed.wxpython import gmEditArea 
  36  from Gnumed.wxpython import gmEMRStructWidgets 
  37  from Gnumed.wxpython import gmFamilyHistoryWidgets 
  38  from Gnumed.wxpython import gmVaccWidgets 
  39  from Gnumed.wxpython import gmDocumentWidgets 
  40  from Gnumed.wxpython import gmGuiHelpers 
  41   
  42   
  43  _log = logging.getLogger('gm.patient') 
  44  #============================================================ 
  45  from Gnumed.wxGladeWidgets import wxgPatientOverviewPnl 
  46   
47 -class cPatientOverviewPnl(wxgPatientOverviewPnl.wxgPatientOverviewPnl, gmRegetMixin.cRegetOnPaintMixin):
48
49 - def __init__(self, *args, **kwargs):
50 wxgPatientOverviewPnl.wxgPatientOverviewPnl.__init__(self, *args, **kwargs) 51 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 52 53 self.__init_ui() 54 self.__register_interests()
55 #-------------------------------------------------------- 56 # internal API 57 #--------------------------------------------------------
58 - def __init_ui(self):
59 # left 60 self._LCTRL_identity.set_columns(columns = [u'']) 61 self._LCTRL_identity.item_tooltip_callback = self._calc_identity_item_tooltip 62 self._LCTRL_identity.activate_callback = self._on_identity_item_activated 63 64 self._LCTRL_contacts.set_columns(columns = [u'']) 65 self._LCTRL_contacts.item_tooltip_callback = self._calc_contacts_list_item_tooltip 66 self._LCTRL_contacts.activate_callback = self._on_contacts_item_activated 67 68 self._LCTRL_encounters.set_columns(columns = [u'']) 69 self._LCTRL_encounters.item_tooltip_callback = self._calc_encounters_list_item_tooltip 70 self._LCTRL_encounters.activate_callback = self._on_encounter_activated 71 72 # middle 73 self._LCTRL_problems.set_columns(columns = [u'']) 74 self._LCTRL_problems.item_tooltip_callback = self._calc_problem_list_item_tooltip 75 self._LCTRL_problems.activate_callback = self._on_problem_activated 76 77 self._LCTRL_meds.set_columns(columns = [u'']) 78 self._LCTRL_meds.item_tooltip_callback = self._calc_meds_list_item_tooltip 79 self._LCTRL_meds.activate_callback = self._on_meds_item_activated 80 81 self._LCTRL_history.set_columns(columns = [u'']) 82 self._LCTRL_history.item_tooltip_callback = self._calc_history_list_item_tooltip 83 self._LCTRL_history.activate_callback = self._on_history_item_activated 84 85 # right hand side 86 self._LCTRL_inbox.set_columns(columns = [u'']) 87 self._LCTRL_inbox.item_tooltip_callback = self._calc_inbox_item_tooltip 88 self._LCTRL_inbox.activate_callback = self._on_inbox_item_activated 89 90 self._LCTRL_results.set_columns(columns = [u'']) 91 self._LCTRL_results.item_tooltip_callback = self._calc_results_list_item_tooltip 92 self._LCTRL_results.activate_callback = self._on_result_activated 93 94 self._LCTRL_documents.set_columns(columns = [u'']) 95 self._LCTRL_documents.item_tooltip_callback = self._calc_documents_list_item_tooltip 96 self._LCTRL_documents.activate_callback = self._on_document_activated
97 #--------------------------------------------------------
98 - def __reset_ui_content(self):
99 self._LCTRL_identity.set_string_items() 100 self._LCTRL_contacts.set_string_items() 101 self._LCTRL_encounters.set_string_items() 102 self._PRW_encounter_range.SetText(value = u'', data = None) 103 104 self._LCTRL_problems.set_string_items() 105 self._LCTRL_meds.set_string_items() 106 self._LCTRL_history.set_string_items() 107 108 self._LCTRL_inbox.set_string_items() 109 self._LCTRL_results.set_string_items() 110 self._LCTRL_documents.set_string_items()
111 #----------------------------------------------------- 112 # event handling 113 #----------------------------------------------------- 114 # remember to call 115 # self._schedule_data_reget() 116 # whenever you learn of data changes from database listener 117 # threads, dispatcher signals etc.
118 - def __register_interests(self):
119 # client internal signals 120 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection) 121 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection) 122 123 # database change signals 124 gmDispatcher.connect(signal = u'identity_mod_db', receiver = self._on_post_patient_selection) 125 gmDispatcher.connect(signal = u'name_mod_db', receiver = self._on_post_patient_selection) 126 gmDispatcher.connect(signal = u'comm_channel_mod_db', receiver = self._on_post_patient_selection) 127 gmDispatcher.connect(signal = u'job_mod_db', receiver = self._on_post_patient_selection) 128 # no signal for external IDs yet 129 # no signal for address yet 130 #gmDispatcher.connect(signal = u'current_encounter_modified', receiver = self._on_current_encounter_modified) 131 #gmDispatcher.connect(signal = u'current_encounter_switched', receiver = self._on_current_encounter_switched) 132 133 gmDispatcher.connect(signal = u'episode_mod_db', receiver = self._on_episode_issue_mod_db) 134 gmDispatcher.connect(signal = u'health_issue_mod_db', receiver = self._on_episode_issue_mod_db) 135 136 gmDispatcher.connect(signal = u'substance_intake_mod_db', receiver = self._on_post_patient_selection) 137 138 gmDispatcher.connect(signal = u'hospital_stay_mod_db', receiver = self._on_post_patient_selection) 139 gmDispatcher.connect(signal = u'family_history_mod_db', receiver = self._on_post_patient_selection) 140 gmDispatcher.connect(signal = u'procedure_mod_db', receiver = self._on_post_patient_selection) 141 gmDispatcher.connect(signal = u'vacc_mod_db', receiver = self._on_post_patient_selection) 142 143 gmDispatcher.connect(signal = u'message_inbox_mod_db', receiver = self._on_post_patient_selection) 144 gmDispatcher.connect(signal = u'test_result_mod_db', receiver = self._on_post_patient_selection) 145 gmDispatcher.connect(signal = u'reviewed_test_results_mod_db', receiver = self._on_post_patient_selection) 146 gmDispatcher.connect(signal = u'doc_mod_db', receiver = self._on_post_patient_selection) 147 148 # synchronous signals 149 # self.__pat.register_pre_selection_callback(callback = self._pre_selection_callback) 150 # gmDispatcher.send(signal = u'register_pre_exit_callback', callback = self._pre_exit_callback) 151 152 self._PRW_encounter_range.add_callback_on_selection(callback = self._on_encounter_range_selected)
153 #--------------------------------------------------------
154 - def _on_encounter_range_selected(self, data):
155 wx.CallAfter(self.__refresh_encounters, patient = gmPerson.gmCurrentPatient())
156 #--------------------------------------------------------
157 - def _on_pre_patient_selection(self):
158 # only empty out here, do NOT access the patient 159 # or else we will access the old patient while it 160 # may not be valid anymore ... 161 wx.CallAfter(self.__reset_ui_content)
162 #--------------------------------------------------------
163 - def _on_post_patient_selection(self):
164 wx.CallAfter(self._schedule_data_reget)
165 #--------------------------------------------------------
166 - def _on_episode_issue_mod_db(self):
167 wx.CallAfter(self._schedule_data_reget)
168 #----------------------------------------------------- 169 # reget-on-paint mixin API 170 #-----------------------------------------------------
171 - def _populate_with_data(self):
172 pat = gmPerson.gmCurrentPatient() 173 if not pat.connected: 174 self.__reset_ui_content() 175 return True 176 177 self.__refresh_identity(patient = pat) 178 self.__refresh_contacts(patient = pat) 179 self.__refresh_encounters(patient = pat) 180 181 self.__refresh_problems(patient = pat) 182 self.__refresh_meds(patient = pat) 183 self.__refresh_history(patient = pat) 184 185 self.__refresh_inbox(patient = pat) 186 self.__refresh_results(patient = pat) 187 self.__refresh_documents(patient = pat) 188 189 return True
190 #----------------------------------------------------- 191 # internal helpers 192 #-----------------------------------------------------
193 - def __refresh_results(self, patient=None):
194 list_items = [] 195 list_data = [] 196 197 emr = patient.get_emr() 198 most_recent = emr.get_most_recent_result() 199 if most_recent is None: 200 self._LCTRL_results.set_string_items(items = []) 201 self._LCTRL_results.set_data(data = []) 202 return 203 204 list_items.append(_('Latest: %s ago (%s %s %s %s%s)') % ( 205 gmDateTime.format_interval_medically(gmDateTime.pydt_now_here() - most_recent['clin_when']), 206 most_recent['unified_abbrev'], 207 most_recent['unified_val'], 208 most_recent['val_unit'], 209 gmTools.coalesce(most_recent['abnormality_indicator'], u'', u' %s'), 210 gmTools.bool2subst(most_recent['reviewed'], u'', u' %s' % gmTools.u_writing_hand) 211 )) 212 list_data.append(most_recent) 213 most_recent_needs_red = False 214 if most_recent['is_technically_abnormal'] is True: 215 if most_recent['is_clinically_relevant']: 216 most_recent_needs_red = True 217 else: 218 if most_recent['abnormality_indicator'] not in [None, u'']: 219 most_recent_needs_red = True 220 221 unsigned = emr.get_unsigned_results(order_by = u"(trim(coalesce(abnormality_indicator), '') <> '') DESC NULLS LAST, unified_abbrev") 222 no_of_reds = 0 223 for result in unsigned: 224 if result['pk_test_result'] == most_recent['pk_test_result']: 225 continue 226 if result['abnormality_indicator'] is not None: 227 if result['abnormality_indicator'].strip() != u'': 228 no_of_reds += 1 229 list_items.append(_('%s %s %s %s (%s ago, %s)') % ( 230 result['unified_abbrev'], 231 result['unified_val'], 232 result['val_unit'], 233 gmTools.coalesce(result['abnormality_indicator'], u'', u' %s'), 234 gmDateTime.format_interval_medically(gmDateTime.pydt_now_here() - result['clin_when']), 235 gmTools.u_writing_hand 236 )) 237 list_data.append(result) 238 239 self._LCTRL_results.set_string_items(items = list_items) 240 self._LCTRL_results.set_data(data = list_data) 241 242 if most_recent_needs_red: 243 self._LCTRL_results.SetItemTextColour(0, wx.NamedColour('RED')) 244 if no_of_reds > 0: 245 for idx in range(1, no_of_reds + 1): 246 self._LCTRL_results.SetItemTextColour(idx, wx.NamedColour('RED'))
247 #-----------------------------------------------------
248 - def _calc_results_list_item_tooltip(self, data):
249 return u'\n'.join(data.format())
250 #-----------------------------------------------------
251 - def _on_result_activated(self, event):
252 # data = self._LCTRL_inbox.get_selected_item_data(only_one = True) 253 # 254 # if data is not None: 255 # # <ctrl> down ? 256 # if wx.GetKeyState(wx.WXK_CONTROL): 257 # if isinstance(data, gmProviderInbox.cInboxMessage): 258 # xxxxxxxxx 259 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmMeasurementsGridPlugin') 260 return
261 #----------------------------------------------------- 262 #-----------------------------------------------------
263 - def __refresh_inbox(self, patient=None):
264 list_items = [] 265 list_data = [] 266 267 due_messages = patient.due_messages 268 no_of_dues = len(due_messages) 269 for msg in due_messages: 270 list_items.append(_('due %s: %s') % ( 271 gmDateTime.format_interval_medically(msg['interval_due']), 272 gmTools.coalesce(msg['comment'], u'?') 273 )) 274 list_data.append(msg) 275 276 for msg in patient.messages: 277 # already displayed above ? 278 if msg['is_due']: 279 continue 280 # not relevant anymore ? 281 if msg['is_expired']: 282 continue 283 list_items.append(u'%s%s' % ( 284 msg['l10n_type'], 285 gmTools.coalesce(msg['comment'], u'', u': %s') 286 )) 287 list_data.append(msg) 288 289 for hint in patient.dynamic_hints: 290 list_items.append(hint['title']) 291 list_data.append(hint) 292 293 self._LCTRL_inbox.set_string_items(items = list_items) 294 self._LCTRL_inbox.set_data(data = list_data) 295 296 if no_of_dues > 0: 297 for idx in range(no_of_dues): 298 self._LCTRL_inbox.SetItemTextColour(idx, wx.NamedColour('RED'))
299 #-----------------------------------------------------
300 - def _calc_inbox_item_tooltip(self, data):
301 if isinstance(data, gmProviderInbox.cInboxMessage): 302 return data.format() 303 304 if isinstance(data, gmProviderInbox.cDynamicHint): 305 return u'%s\n\n%s\n\n%s %s' % ( 306 data['title'], 307 gmTools.wrap(data['hint'], width = 50), 308 gmTools.wrap(gmTools.coalesce(data['url'], u'', u'%s\n\n'), width = 50), 309 data['source'] 310 ) 311 312 return None
313 #-----------------------------------------------------
314 - def _on_inbox_item_activated(self, event):
315 316 data = self._LCTRL_inbox.get_selected_item_data(only_one = True) 317 318 if isinstance(data, gmProviderInbox.cDynamicHint): 319 if data['url'] is not None: 320 gmNetworkTools.open_url_in_browser(data['url']) 321 return 322 323 # <ctrl> down ? 324 if not wx.GetKeyState(wx.WXK_CONTROL): 325 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin') 326 return 327 328 if data is None: 329 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin') 330 return 331 332 if not isinstance(data, gmProviderInbox.cInboxMessage): 333 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin') 334 return 335 336 delete_it = gmGuiHelpers.gm_show_question ( 337 question = _('Do you really want to\ndelete this inbox message ?'), 338 title = _('Deleting inbox message') 339 ) 340 if not delete_it: 341 return 342 343 gmProviderInbox.delete_inbox_message(inbox_message = data['pk_inbox_message']) 344 return
345 #----------------------------------------------------- 346 #-----------------------------------------------------
347 - def __refresh_documents(self, patient=None):
348 doc_folder = patient.get_document_folder() 349 350 list_items = [] 351 list_data = [] 352 353 docs = doc_folder.get_unsigned_documents() 354 no_of_unsigned = len(docs) 355 for doc in docs: 356 list_items.append(u'%s %s (%s)' % ( 357 gmDateTime.pydt_strftime(doc['clin_when'], format = '%m/%Y', accuracy = gmDateTime.acc_months), 358 doc['l10n_type'], 359 gmTools.u_writing_hand 360 )) 361 list_data.append(doc) 362 363 docs = doc_folder.get_documents(order_by = u'ORDER BY clin_when DESC', exclude_unsigned = True) 364 for doc in docs[:5]: 365 list_items.append(u'%s %s' % ( 366 gmDateTime.pydt_strftime(doc['clin_when'], format = '%m/%Y', accuracy = gmDateTime.acc_months), 367 doc['l10n_type'] 368 )) 369 list_data.append(doc) 370 if len(docs) > 5: 371 list_items.append(_('%s %s more not shown %s') % ( 372 gmTools.u_ellipsis, 373 len(docs) - 5, 374 gmTools.u_ellipsis 375 )) 376 list_data.append(u'') 377 378 self._LCTRL_documents.set_string_items(items = list_items) 379 self._LCTRL_documents.set_data(data = list_data) 380 381 if no_of_unsigned > 0: 382 for idx in range(no_of_unsigned): 383 self._LCTRL_documents.SetItemTextColour(idx, wx.NamedColour('RED'))
384 #-----------------------------------------------------
385 - def _calc_documents_list_item_tooltip(self, data):
386 emr = gmPerson.gmCurrentPatient().get_emr() 387 388 if isinstance(data, gmDocuments.cDocument): 389 return data.format() 390 391 return None
392 #-----------------------------------------------------
393 - def _on_document_activated(self, event):
394 data = self._LCTRL_documents.get_selected_item_data(only_one = True) 395 396 if data is not None: 397 # <ctrl> down ? 398 if wx.GetKeyState(wx.WXK_CONTROL): 399 if isinstance(data, gmDocuments.cDocument): 400 if len(data.parts) > 0: 401 gmDocumentWidgets.display_document_part(parent = self, part = data.parts[0]) 402 else: 403 gmDocumentWidgets.review_document(parent = self, document = data) 404 return 405 406 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmShowMedDocs') 407 return
408 #----------------------------------------------------- 409 #-----------------------------------------------------
410 - def __refresh_encounters(self, patient=None):
411 412 cover_period = self._PRW_encounter_range.GetData() 413 if cover_period is None: 414 if self._PRW_encounter_range.GetValue().strip() != u'': 415 return 416 417 emr = patient.get_emr() 418 419 list_items = [] 420 list_data = [] 421 422 is_waiting = False 423 wlist = patient.get_waiting_list_entry() 424 if len(wlist) > 0: 425 is_waiting = True 426 w = wlist[0] 427 list_items.append(_('Currently in waiting list [%s]') % w['waiting_zone']) 428 list_data.append({'wlist': gmTools.coalesce(w['comment'], None)}) 429 430 first = emr.get_first_encounter() 431 if first is not None: 432 list_items.append ( 433 _('first: %s, %s') % ( 434 gmDateTime.pydt_strftime ( 435 first['started'], 436 format = '%Y %b %d', 437 accuracy = gmDateTime.acc_days 438 ), 439 first['l10n_type'] 440 ) 441 ) 442 list_data.append(first) 443 444 last = emr.get_last_but_one_encounter() 445 if last is not None: 446 list_items.append ( 447 _('last: %s, %s') % ( 448 gmDateTime.pydt_strftime ( 449 last['started'], 450 format = '%Y %b %d', 451 accuracy = gmDateTime.acc_days 452 ), 453 last['l10n_type'] 454 ) 455 ) 456 list_data.append(last) 457 458 encs = emr.get_encounter_stats_by_type(cover_period = cover_period) 459 for enc in encs: 460 item = u'%s x %s' % (enc['frequency'], enc['l10n_type']) 461 list_items.append(item) 462 list_data.append(item) 463 464 stays = emr.get_hospital_stay_stats_by_hospital(cover_period = cover_period) 465 for stay in stays: 466 item = u'%s x %s' % ( 467 stay['frequency'], 468 stay['hospital'] 469 ) 470 list_items.append(item) 471 list_data.append({'stay': item}) 472 473 self._LCTRL_encounters.set_string_items(items = list_items) 474 self._LCTRL_encounters.set_data(data = list_data) 475 if is_waiting: 476 self._LCTRL_encounters.SetItemTextColour(0, wx.NamedColour('RED'))
477 #-----------------------------------------------------
478 - def _calc_encounters_list_item_tooltip(self, data):
479 emr = gmPerson.gmCurrentPatient().get_emr() 480 481 if isinstance(data, gmEMRStructItems.cEncounter): 482 return data.format ( 483 with_vaccinations = False, 484 with_tests = False, 485 with_docs = False, 486 with_co_encountlet_hints = True, 487 with_rfe_aoe = True 488 ) 489 490 if type(data) == type({}): 491 key, val = data.items()[0] 492 if key == 'wlist': 493 return val 494 if key == 'stay': 495 return None 496 497 return data
498 #-----------------------------------------------------
499 - def _on_encounter_activated(self, event):
500 data = self._LCTRL_encounters.get_selected_item_data(only_one = True) 501 if data is not None: 502 # <ctrl> down ? 503 if wx.GetKeyState(wx.WXK_CONTROL): 504 if isinstance(data, gmEMRStructItems.cEncounter): 505 gmEMRStructWidgets.edit_encounter(parent = self, encounter = data) 506 return 507 508 if type(data) == type({}): 509 key, val = data.items()[0] 510 if key == 'wlist': 511 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmWaitingListPlugin') 512 return 513 if key == 'stay': 514 wx.CallAfter(gmEMRStructWidgets.manage_hospital_stays, parent = self) 515 return 516 517 wx.CallAfter(gmEMRStructWidgets.manage_encounters, parent = self, ignore_OK_button = False)
518 #----------------------------------------------------- 519 #-----------------------------------------------------
520 - def __refresh_history(self, patient=None):
521 emr = patient.get_emr() 522 523 list_items = [] 524 list_data = [] 525 526 issues = [ 527 i for i in emr.get_health_issues() 528 if ((i['clinically_relevant'] is False) or (i['is_active'] is False)) 529 ] 530 for issue in issues: 531 last_encounter = emr.get_last_encounter(issue_id = issue['pk_health_issue']) 532 if last_encounter is None: 533 last = issue['modified_when'].strftime('%m/%Y') 534 else: 535 last = last_encounter['last_affirmed'].strftime('%m/%Y') 536 list_items.append(u'%s %s' % (last, issue['description'])) 537 list_data.append(issue) 538 del issues 539 540 fhxs = emr.get_family_history() 541 for fhx in fhxs: 542 list_items.append(u'%s: %s%s' % ( 543 fhx['l10n_relation'], 544 fhx['condition'], 545 gmTools.coalesce(fhx['age_noted'], u'', u' (@ %s)') 546 )) 547 list_data.append(fhx) 548 del fhxs 549 550 stays = emr.get_hospital_stays() 551 for stay in stays: 552 if stay['discharge'] is not None: 553 discharge = u'' 554 else: 555 discharge = gmTools.u_ellipsis 556 list_items.append(u'%s%s %s: %s' % ( 557 gmDateTime.pydt_strftime(stay['admission'], format = '%Y %b %d'), 558 discharge, 559 stay['hospital'], 560 stay['episode'] 561 )) 562 list_data.append(stay) 563 del stays 564 565 procs = emr.get_performed_procedures() 566 for proc in procs: 567 list_items.append(u'%s%s %s' % ( 568 gmDateTime.pydt_strftime(proc['clin_when'], format = '%Y %b %d'), 569 gmTools.bool2subst(proc['is_ongoing'], gmTools.u_ellipsis, u'', u''), 570 proc['performed_procedure'] 571 )) 572 list_data.append(proc) 573 del procs 574 575 vaccs = emr.get_latest_vaccinations() 576 for ind, tmp in vaccs.items(): 577 tmp, vacc = tmp 578 list_items.append(_('%s Vacc: %s') % ( 579 gmDateTime.pydt_strftime(vacc['date_given'], format = '%Y %b %d'), 580 ind 581 )) 582 list_data.append(vacc) 583 del vaccs 584 585 self._LCTRL_history.set_string_items(items = list_items) 586 self._LCTRL_history.set_data(data = list_data)
587 #-----------------------------------------------------
588 - def _calc_history_list_item_tooltip(self, data):
589 590 if isinstance(data, gmEMRStructItems.cHealthIssue): 591 return data.format ( 592 patient = gmPerson.gmCurrentPatient(), 593 with_medications = False, 594 with_hospital_stays = False, 595 with_procedures = False, 596 with_family_history = False, 597 with_documents = False, 598 with_tests = False, 599 with_vaccinations = False 600 ).strip(u'\n') 601 602 if isinstance(data, gmFamilyHistory.cFamilyHistory): 603 return data.format(include_episode = True, include_comment = True) 604 605 if isinstance(data, gmEMRStructItems.cHospitalStay): 606 return data.format() 607 608 if isinstance(data, gmEMRStructItems.cPerformedProcedure): 609 return data.format(include_episode = True) 610 611 if isinstance(data, gmVaccination.cVaccination): 612 return u'\n'.join(data.format ( 613 with_indications = True, 614 with_comment = True, 615 with_reaction = True, 616 date_format = '%Y %b %d' 617 )) 618 619 return None
620 #-----------------------------------------------------
621 - def _on_history_item_activated(self, event):
622 data = self._LCTRL_history.get_selected_item_data(only_one = True) 623 if data is None: 624 return 625 626 # <ctrl> down ? 627 if wx.GetKeyState(wx.WXK_CONTROL): 628 if isinstance(data, gmEMRStructItems.cHealthIssue): 629 gmEMRStructWidgets.edit_health_issue(parent = self, issue = data) 630 return 631 if isinstance(data, gmFamilyHistory.cFamilyHistory): 632 FamilyHistoryWidgets.edit_family_history(parent = self, family_history = data) 633 return 634 if isinstance(data, gmEMRStructItems.cHospitalStay): 635 gmEMRStructWidgets.edit_hospital_stay(parent = self, hospital_stay = data) 636 return 637 if isinstance(data, gmEMRStructItems.cPerformedProcedure): 638 gmEMRStructWidgets.edit_procedure(parent = self, procedure = data) 639 return 640 if isinstance(data, gmVaccination.cVaccination): 641 gmVaccWidgets.edit_vaccination(parent = self, vaccination = data, single_entry = True) 642 return 643 return 644 645 if isinstance(data, gmEMRStructItems.cHealthIssue): 646 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmEMRBrowserPlugin') 647 return 648 if isinstance(data, gmFamilyHistory.cFamilyHistory): 649 FamilyHistoryWidgets.manage_family_history(parent = self) 650 return 651 if isinstance(data, gmEMRStructItems.cHospitalStay): 652 gmEMRStructWidgets.manage_hospital_stays(parent = self) 653 return 654 if isinstance(data, gmEMRStructItems.cPerformedProcedure): 655 gmEMRStructWidgets.manage_performed_procedures(parent = self) 656 return 657 if isinstance(data, gmVaccination.cVaccination): 658 gmVaccWidgets.manage_vaccinations(parent = self) 659 return 660 661 return
662 #----------------------------------------------------- 663 #-----------------------------------------------------
664 - def __refresh_meds(self, patient=None):
665 # list by brand or substance: 666 emr = patient.get_emr() 667 intakes = emr.get_current_substance_intake(include_inactive = False, include_unapproved = True, order_by = u'substance') 668 669 list_items = [] 670 multi_brands_already_seen = [] 671 for intake in intakes: 672 brand = intake.containing_drug 673 if brand is None or len(brand['pk_components']) == 1: 674 list_items.append(_('%s %s %s%s') % ( 675 intake['substance'], 676 intake['amount'], 677 intake['unit'], 678 gmTools.coalesce ( 679 intake['schedule'], 680 u'', 681 u': %s' 682 ) 683 )) 684 else: 685 if intake['brand'] in multi_brands_already_seen: 686 continue 687 multi_brands_already_seen.append(intake['brand']) 688 list_items.append(_('%s %s%s') % ( 689 intake['brand'], 690 brand['preparation'], 691 gmTools.coalesce ( 692 intake['schedule'], 693 u'', 694 u': %s' 695 ) 696 )) 697 self._LCTRL_meds.set_string_items(items = list_items) 698 self._LCTRL_meds.set_data(data = intakes)
699 #-----------------------------------------------------
700 - def _calc_meds_list_item_tooltip(self, data):
701 emr = gmPerson.gmCurrentPatient().get_emr() 702 atcs = [] 703 if data['atc_substance'] is not None: 704 atcs.append(data['atc_substance']) 705 # if data['atc_brand'] is not None: 706 # atcs.append(data['atc_brand']) 707 # allg = emr.is_allergic_to(atcs = tuple(atcs), inns = (data['substance'],), brand = data['brand']) 708 allg = emr.is_allergic_to(atcs = tuple(atcs), inns = (data['substance'],)) 709 if allg is False: 710 allg = None 711 return data.format(one_line = False, allergy = allg, show_all_brand_components = True)
712 #-----------------------------------------------------
713 - def _on_meds_item_activated(self, event):
714 data = self._LCTRL_meds.get_selected_item_data(only_one = True) 715 if data is not None: 716 # <ctrl> down ? 717 if wx.GetKeyState(wx.WXK_CONTROL): 718 wx.CallAfter(gmMedicationWidgets.edit_intake_of_substance, parent = self, substance = data) 719 return 720 721 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmCurrentSubstancesPlugin')
722 #----------------------------------------------------- 723 #-----------------------------------------------------
724 - def __refresh_contacts(self, patient=None):
725 emr = patient.get_emr() 726 727 list_items = [] 728 list_data = [] 729 is_in_hospital = False 730 731 stays = emr.get_hospital_stays(ongoing_only = True) 732 if len(stays) > 0: 733 list_items.append(_('** Currently hospitalized: %s **') % stays[0]['hospital']) 734 list_data.append(stays[0]) 735 is_in_hospital = True 736 737 adrs = patient.get_addresses() 738 for adr in adrs: 739 list_items.append(adr.format(single_line = True, verbose = False, show_type = True)) 740 list_data.append(adr) 741 742 comms = patient.get_comm_channels() 743 for comm in comms: 744 list_items.append(u'%s: %s' % ( 745 comm['l10n_comm_type'], 746 comm['url'] 747 )) 748 list_data.append(comm) 749 750 ident = patient.emergency_contact_in_database 751 if ident is not None: 752 list_items.append(_('emergency: %s') % ident['description_gender']) 753 list_data.append(ident) 754 755 if patient['emergency_contact'] is not None: 756 list_items.append(_('emergency: %s') % patient['emergency_contact'].split(u'\n')[0]) 757 list_data.append(patient['emergency_contact']) 758 759 provider = patient.primary_provider 760 if provider is not None: 761 list_items.append(_('in-praxis: %s') % provider.identity['description_gender']) 762 list_data.append(provider) 763 764 self._LCTRL_contacts.set_string_items(items = list_items) 765 self._LCTRL_contacts.set_data(data = list_data) 766 if is_in_hospital: 767 self._LCTRL_contacts.SetItemTextColour(0, wx.NamedColour('RED'))
768 #-----------------------------------------------------
769 - def _calc_contacts_list_item_tooltip(self, data):
770 771 if isinstance(data, gmEMRStructItems.cHospitalStay): 772 return data.format() 773 774 if isinstance(data, gmDemographicRecord.cPatientAddress): 775 return u'\n'.join(data.format()) 776 777 if isinstance(data, gmDemographicRecord.cCommChannel): 778 return gmTools.bool2subst ( 779 data['is_confidential'], 780 _('*** CONFIDENTIAL ***'), 781 None 782 ) 783 784 if isinstance(data, gmPerson.cIdentity): 785 return u'%s\n\n%s' % ( 786 data['description_gender'], 787 u'\n'.join([ 788 u'%s: %s%s' % ( 789 c['l10n_comm_type'], 790 c['url'], 791 gmTools.bool2subst(c['is_confidential'], _(' (confidential !)'), u'', u'') 792 ) 793 for c in data.get_comm_channels() 794 ]) 795 ) 796 797 if isinstance(data, basestring): 798 return data 799 800 if isinstance(data, gmStaff.cStaff): 801 ident = data.identity 802 return u'%s: %s\n\n%s%s' % ( 803 data['short_alias'], 804 ident['description_gender'], 805 u'\n'.join([ 806 u'%s: %s%s' % ( 807 c['l10n_comm_type'], 808 c['url'], 809 gmTools.bool2subst(c['is_confidential'], _(' (confidential !)'), u'', u'') 810 ) 811 for c in ident.get_comm_channels() 812 ]), 813 gmTools.coalesce(data['comment'], u'', u'\n\n%s') 814 ) 815 816 return None
817 #-----------------------------------------------------
818 - def _on_contacts_item_activated(self, event):
819 data = self._LCTRL_contacts.get_selected_item_data(only_one = True) 820 if data is not None: 821 # <ctrl> down ? 822 if wx.GetKeyState(wx.WXK_CONTROL): 823 if isinstance(data, gmEMRStructItems.cHospitalStay): 824 gmEMRStructWidgets.edit_hospital_stay(parent = self, hospital_stay = data) 825 return 826 if isinstance(data, gmDemographicRecord.cPatientAddress): 827 pass 828 if isinstance(data, gmDemographicRecord.cCommChannel): 829 gmContactWidgets.edit_comm_channel(parent = self, comm_channel = data, channel_owner = gmPerson.gmCurrentPatient()) 830 return 831 if isinstance(data, gmPerson.cIdentity): 832 pass 833 if isinstance(data, gmStaff.cStaff): 834 pass 835 836 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin')
837 #----------------------------------------------------- 838 #-----------------------------------------------------
839 - def __refresh_problems(self, patient=None):
840 emr = patient.get_emr() 841 842 problems = [ 843 p for p in emr.get_problems(include_closed_episodes = False, include_irrelevant_issues = False) 844 if p['problem_active'] 845 ] 846 847 list_items = [] 848 for problem in problems: 849 if problem['type'] == 'issue': 850 issue = emr.problem2issue(problem) 851 last_encounter = emr.get_last_encounter(issue_id = issue['pk_health_issue']) 852 if last_encounter is None: 853 last = issue['modified_when'].strftime('%m/%Y') 854 else: 855 last = last_encounter['last_affirmed'].strftime('%m/%Y') 856 list_items.append(u'%s: %s' % (problem['problem'], last)) 857 858 elif problem['type'] == 'episode': 859 epi = emr.problem2episode(problem) 860 last_encounter = emr.get_last_encounter(episode_id = epi['pk_episode']) 861 if last_encounter is None: 862 last = epi['episode_modified_when'].strftime('%m/%Y') 863 else: 864 last = last_encounter['last_affirmed'].strftime('%m/%Y') 865 list_items.append(u'%s: %s' % (problem['problem'], last)) 866 867 self._LCTRL_problems.set_string_items(items = list_items) 868 self._LCTRL_problems.set_data(data = problems)
869 #-----------------------------------------------------
870 - def _calc_problem_list_item_tooltip(self, data):
871 emr = gmPerson.gmCurrentPatient().get_emr() 872 873 if data['type'] == 'issue': 874 issue = emr.problem2issue(data) 875 tt = issue.format ( 876 patient = gmPerson.gmCurrentPatient(), 877 with_medications = False, 878 with_hospital_stays = False, 879 with_procedures = False, 880 with_family_history = False, 881 with_documents = False, 882 with_tests = False, 883 with_vaccinations = False 884 ).strip(u'\n') 885 return tt 886 887 if data['type'] == 'episode': 888 epi = emr.problem2episode(data) 889 tt = epi.format ( 890 patient = gmPerson.gmCurrentPatient(), 891 with_encounters = False, 892 with_hospital_stays = False, 893 with_procedures = False, 894 with_family_history = False, 895 with_documents = False, 896 with_tests = False, 897 with_vaccinations = False, 898 with_health_issue = True 899 ).strip(u'\n') 900 return tt 901 902 return None
903 #-----------------------------------------------------
904 - def _on_problem_activated(self, event):
905 data = self._LCTRL_problems.get_selected_item_data(only_one = True) 906 if data is not None: 907 # <ctrl> down ? 908 if wx.GetKeyState(wx.WXK_CONTROL): 909 emr = gmPerson.gmCurrentPatient().get_emr() 910 if data['type'] == 'issue': 911 gmEMRStructWidgets.edit_health_issue(parent = self, issue = emr.problem2issue(data)) 912 return 913 if data['type'] == 'episode': 914 gmEMRStructWidgets.edit_episode(parent = self, episode = emr.problem2episode(data)) 915 return 916 917 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmEMRBrowserPlugin')
918 #----------------------------------------------------- 919 #-----------------------------------------------------
920 - def __refresh_identity(self, patient=None):
921 # names (.comment -> tooltip) 922 names = patient.get_names(exclude_active = True) 923 items = [ 924 _('aka: %(last)s, %(first)s%(nick)s') % { 925 'last': n['lastnames'], 926 'first': n['firstnames'], 927 'nick': gmTools.coalesce(n['preferred'], u'', u" '%s'") 928 } for n in names 929 ] 930 data = names 931 932 # IDs (.issuer & .comment -> tooltip) 933 ids = patient.external_ids 934 for i in ids: 935 items.append(u'%(name)s: %(value)s' % i) 936 data.append({'id': i}) 937 938 # occupation 939 jobs = patient.get_occupations() 940 for j in jobs: 941 items.append(_('job: %s') % j['l10n_occupation']) 942 data.append({'job': j}) 943 944 self._LCTRL_identity.set_string_items(items = items) 945 self._LCTRL_identity.set_data(data = data)
946 #-----------------------------------------------------
947 - def _calc_identity_item_tooltip(self, data):
948 if isinstance(data, gmPerson.cPersonName): 949 return data['comment'] 950 if isinstance(data, type({})): 951 key = data.keys()[0] 952 val = data[key] 953 if key == 'id': 954 return _('issued by: %s%s') % ( 955 val['issuer'], 956 gmTools.coalesce(val['comment'], u'', u'\n\n%s') 957 ) 958 if key == 'job': 959 if val['activities'] is None: 960 return None 961 return _('Activities:\n\n%s') % val['activities'] 962 963 return None
964 #-----------------------------------------------------
965 - def _on_identity_item_activated(self, event):
966 data = self._LCTRL_identity.get_selected_item_data(only_one = True) 967 if data is not None: 968 # <ctrl> down ? 969 if wx.GetKeyState(wx.WXK_CONTROL): 970 if isinstance(data, gmPerson.cPersonName): 971 ea = gmDemographicsWidgets.cPersonNameEAPnl(self, -1, name = data) 972 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True) 973 dlg.SetTitle(_('Cloning name')) 974 dlg.ShowModal() 975 return 976 if isinstance(data, type({})): 977 key = data.keys()[0] 978 val = data[key] 979 if key == 'id': 980 ea = gmDemographicsWidgets.cExternalIDEditAreaPnl(self, -1, external_id = val) 981 ea.identity = gmPerson.gmCurrentPatient() 982 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True) 983 dlg.SetTitle(_('Editing external ID')) 984 dlg.ShowModal() 985 return 986 if key == 'job': 987 gmDemographicsWidgets.edit_occupation() 988 return 989 990 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin')
991 #============================================================ 992 # main 993 #------------------------------------------------------------ 994 if __name__ == "__main__": 995 996 if len(sys.argv) < 2: 997 sys.exit() 998 999 if sys.argv[1] != u'test': 1000 sys.exit() 1001 1002 # from Gnumed.pycommon import gmPG2 1003 # from Gnumed.pycommon import gmI18N 1004 # gmI18N.activate_locale() 1005 # gmI18N.install_domain() 1006 1007 #-------------------------------------------------------- 1008 #test_org_unit_prw() 1009