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