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

Source Code for Module Gnumed.wxpython.gmProviderInboxWidgets

  1  """GNUmed provider inbox handling widgets. 
  2  """ 
  3  #================================================================ 
  4  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>" 
  5  __license__ = "GPL v2 or later" 
  6   
  7  import sys 
  8  import logging 
  9   
 10   
 11  import wx 
 12   
 13   
 14  if __name__ == '__main__': 
 15          sys.path.insert(0, '../../') 
 16  from Gnumed.pycommon import gmI18N 
 17  from Gnumed.pycommon import gmExceptions 
 18  from Gnumed.pycommon import gmPG2 
 19  from Gnumed.pycommon import gmTools 
 20  from Gnumed.pycommon import gmDispatcher 
 21  from Gnumed.pycommon import gmMatchProvider 
 22  from Gnumed.pycommon import gmDateTime 
 23   
 24  from Gnumed.business import gmPerson 
 25  from Gnumed.business import gmStaff 
 26  from Gnumed.business import gmProviderInbox 
 27  from Gnumed.business import gmClinicalRecord 
 28   
 29  from Gnumed.wxpython import gmGuiHelpers 
 30  from Gnumed.wxpython import gmListWidgets 
 31  from Gnumed.wxpython import gmPlugin 
 32  from Gnumed.wxpython import gmRegetMixin 
 33  from Gnumed.wxpython import gmPhraseWheel 
 34  from Gnumed.wxpython import gmEditArea 
 35  from Gnumed.wxpython.gmPatSearchWidgets import set_active_patient 
 36  from Gnumed.wxpython.gmVaccWidgets import manage_vaccinations 
 37   
 38   
 39  _log = logging.getLogger('gm.ui') 
 40   
 41  _indicator = { 
 42          -1: '', 
 43          0: '', 
 44          1: '*!!*' 
 45  } 
 46   
 47  #==================================================================== 
48 -class cMessageTypePhraseWheel(gmPhraseWheel.cPhraseWheel):
49
50 - def __init__(self, *args, **kwargs):
51 52 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 53 54 query = """ 55 SELECT DISTINCT ON (label) 56 pk_type, 57 (l10n_type || ' (' || l10n_category || ')') 58 AS label 59 FROM 60 dem.v_inbox_item_type 61 WHERE 62 l10n_type %(fragment_condition)s 63 OR 64 type %(fragment_condition)s 65 OR 66 l10n_category %(fragment_condition)s 67 OR 68 category %(fragment_condition)s 69 ORDER BY label 70 LIMIT 50""" 71 72 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query) 73 mp.setThresholds(1, 2, 4) 74 self.matcher = mp 75 self.SetToolTip(_('Select a message type.'))
76 #----------------------------------------------------------------
77 - def _create_data(self):
78 if self.GetData() is not None: 79 return 80 81 val = self.GetValue().strip() 82 if val == '': 83 return 84 85 self.SetText ( 86 value = val, 87 data = gmProviderInbox.create_inbox_item_type(message_type = val) 88 )
89 90 #==================================================================== 91 from Gnumed.wxGladeWidgets import wxgInboxMessageEAPnl 92
93 -class cInboxMessageEAPnl(wxgInboxMessageEAPnl.wxgInboxMessageEAPnl, gmEditArea.cGenericEditAreaMixin):
94
95 - def __init__(self, *args, **kwargs):
96 97 try: 98 data = kwargs['message'] 99 del kwargs['message'] 100 except KeyError: 101 data = None 102 103 wxgInboxMessageEAPnl.wxgInboxMessageEAPnl.__init__(self, *args, **kwargs) 104 gmEditArea.cGenericEditAreaMixin.__init__(self) 105 106 # Code using this mixin should set mode and data 107 # after instantiating the class: 108 self.mode = 'new' 109 self.data = data 110 if data is not None: 111 self.mode = 'edit' 112 113 self.__init_ui()
114 #----------------------------------------------------------------
115 - def __init_ui(self):
116 if not gmPerson.gmCurrentPatient().connected: 117 self._CHBOX_active_patient.SetValue(False) 118 self._CHBOX_active_patient.Enable(False) 119 self._PRW_patient.Enable(True)
120 #---------------------------------------------------------------- 121 # generic Edit Area mixin API 122 #----------------------------------------------------------------
123 - def _valid_for_save(self):
124 validity = True 125 126 if self._TCTRL_subject.GetValue().strip() == '': 127 validity = False 128 self.display_ctrl_as_valid(ctrl = self._TCTRL_subject, valid = False) 129 else: 130 self.display_ctrl_as_valid(ctrl = self._TCTRL_subject, valid = True) 131 132 if self._PRW_type.GetValue().strip() == '': 133 validity = False 134 self._PRW_type.display_as_valid(False) 135 else: 136 self._PRW_type.display_as_valid(True) 137 138 missing_receiver = ( 139 (self._CHBOX_send_to_me.IsChecked() is False) 140 and 141 (self._PRW_receiver.GetData() is None) 142 ) 143 144 missing_patient = ( 145 (self._CHBOX_active_patient.IsChecked() is False) 146 and 147 (self._PRW_patient.person is None) 148 ) 149 150 if missing_receiver and missing_patient: 151 validity = False 152 self.display_ctrl_as_valid(ctrl = self._CHBOX_send_to_me, valid = False) 153 self._PRW_receiver.display_as_valid(False) 154 self.display_ctrl_as_valid(ctrl = self._CHBOX_active_patient, valid = False) 155 self.display_ctrl_as_valid(ctrl = self._PRW_patient, valid = False) 156 else: 157 self.display_ctrl_as_valid(ctrl = self._CHBOX_send_to_me, valid = True) 158 self._PRW_receiver.display_as_valid(True) 159 self.display_ctrl_as_valid(ctrl = self._CHBOX_active_patient, valid = True) 160 self.display_ctrl_as_valid(ctrl = self._PRW_patient, valid = True) 161 162 if self._PRW_due.is_valid_timestamp(allow_empty = True): 163 self._PRW_due.display_as_valid(True) 164 else: 165 # non-empty but also not valid 166 validity = False 167 self._PRW_due.display_as_valid(False) 168 169 if self._PRW_expiry.is_valid_timestamp(allow_empty = True): 170 self._PRW_expiry.display_as_valid(True) 171 else: 172 # non-empty but also not valid 173 validity = False 174 self._PRW_expiry.display_as_valid(False) 175 176 # if .due is not empty AND valid 177 if self._PRW_due.is_valid_timestamp(allow_empty = False): 178 # and if .expiry is ALSO not empty AND valid 179 if self._PRW_expiry.is_valid_timestamp(allow_empty = False): 180 # only then compare .due and .expiry 181 if not self._PRW_expiry.date > self._PRW_due.date: 182 validity = False 183 self._PRW_expiry.display_as_valid(False) 184 gmDispatcher.send(signal = 'statustext', msg = _('Message cannot expire before being due.')) 185 186 return validity
187 #----------------------------------------------------------------
188 - def _save_as_new(self):
189 190 pat_id = None 191 if self._CHBOX_active_patient.GetValue() is True: 192 pat_id = gmPerson.gmCurrentPatient().ID 193 else: 194 if self._PRW_patient.person is not None: 195 pat_id = self._PRW_patient.person.ID 196 197 receiver = None 198 if self._CHBOX_send_to_me.IsChecked(): 199 receiver = gmStaff.gmCurrentProvider()['pk_staff'] 200 else: 201 if self._PRW_receiver.GetData() is not None: 202 receiver = self._PRW_receiver.GetData() 203 204 msg = gmProviderInbox.create_inbox_message ( 205 patient = pat_id, 206 staff = receiver, 207 message_type = self._PRW_type.GetData(can_create = True), 208 subject = self._TCTRL_subject.GetValue().strip() 209 ) 210 211 msg['data'] = self._TCTRL_message.GetValue().strip() 212 213 if self._PRW_due.is_valid_timestamp(): 214 msg['due_date'] = self._PRW_due.date 215 216 if self._PRW_expiry.is_valid_timestamp(): 217 msg['expiry_date'] = self._PRW_expiry.date 218 219 if self._RBTN_normal.GetValue() is True: 220 msg['importance'] = 0 221 elif self._RBTN_high.GetValue() is True: 222 msg['importance'] = 1 223 else: 224 msg['importance'] = -1 225 226 msg.save() 227 self.data = msg 228 return True
229 #----------------------------------------------------------------
230 - def _save_as_update(self):
231 232 self.data['comment'] = self._TCTRL_subject.GetValue().strip() 233 self.data['pk_type'] = self._PRW_type.GetData(can_create = True) 234 235 if self._CHBOX_send_to_me.IsChecked(): 236 self.data['pk_staff'] = gmStaff.gmCurrentProvider()['pk_staff'] 237 else: 238 self.data['pk_staff'] = self._PRW_receiver.GetData() 239 240 self.data['data'] = self._TCTRL_message.GetValue().strip() 241 242 if self._CHBOX_active_patient.GetValue() is True: 243 self.data['pk_patient'] = gmPerson.gmCurrentPatient().ID 244 else: 245 if self._PRW_patient.person is None: 246 self.data['pk_patient'] = None 247 else: 248 self.data['pk_patient'] = self._PRW_patient.person.ID 249 250 if self._PRW_due.is_valid_timestamp(): 251 self.data['due_date'] = self._PRW_due.date 252 253 if self._PRW_expiry.is_valid_timestamp(): 254 self.data['expiry_date'] = self._PRW_expiry.date 255 256 if self._RBTN_normal.GetValue() is True: 257 self.data['importance'] = 0 258 elif self._RBTN_high.GetValue() is True: 259 self.data['importance'] = 1 260 else: 261 self.data['importance'] = -1 262 263 self.data.save() 264 return True
265 #----------------------------------------------------------------
266 - def _refresh_as_new(self):
267 self._TCTRL_subject.SetValue('') 268 self._PRW_type.SetText(value = '', data = None) 269 self._CHBOX_send_to_me.SetValue(True) 270 self._PRW_receiver.Enable(False) 271 self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff']) 272 self._TCTRL_message.SetValue('') 273 self._PRW_due.SetText(data = None) 274 self._PRW_expiry.SetText(data = None) 275 self._RBTN_normal.SetValue(True) 276 self._RBTN_high.SetValue(False) 277 self._RBTN_low.SetValue(False) 278 279 self._PRW_patient.person = None 280 281 if gmPerson.gmCurrentPatient().connected: 282 self._CHBOX_active_patient.Enable(True) 283 self._CHBOX_active_patient.SetValue(True) 284 self._PRW_patient.Enable(False) 285 else: 286 self._CHBOX_active_patient.Enable(False) 287 self._CHBOX_active_patient.SetValue(False) 288 self._PRW_patient.Enable(True) 289 290 self._TCTRL_subject.SetFocus()
291 #----------------------------------------------------------------
293 self._refresh_as_new()
294 #----------------------------------------------------------------
295 - def _refresh_from_existing(self):
296 297 self._TCTRL_subject.SetValue(gmTools.coalesce(self.data['comment'], '')) 298 self._PRW_type.SetData(data = self.data['pk_type']) 299 300 curr_prov = gmStaff.gmCurrentProvider() 301 curr_pat = gmPerson.gmCurrentPatient() 302 303 if curr_prov['pk_staff'] == self.data['pk_staff']: 304 self._CHBOX_send_to_me.SetValue(True) 305 self._PRW_receiver.Enable(False) 306 self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff']) 307 else: 308 self._CHBOX_send_to_me.SetValue(False) 309 self._PRW_receiver.Enable(True) 310 self._PRW_receiver.SetData(data = self.data['pk_staff']) 311 312 self._TCTRL_message.SetValue(gmTools.coalesce(self.data['data'], '')) 313 314 if curr_pat.connected: 315 self._CHBOX_active_patient.Enable(True) 316 if curr_pat.ID == self.data['pk_patient']: 317 self._CHBOX_active_patient.SetValue(True) 318 self._PRW_patient.Enable(False) 319 self._PRW_patient.person = None 320 else: 321 self._CHBOX_active_patient.SetValue(False) 322 self._PRW_patient.Enable(True) 323 if self.data['pk_patient'] is None: 324 self._PRW_patient.person = None 325 else: 326 self._PRW_patient.person = gmPerson.cPerson(aPK_obj = self.data['pk_patient']) 327 else: 328 self._CHBOX_active_patient.Enable(False) 329 self._CHBOX_active_patient.SetValue(False) 330 self._PRW_patient.Enable(True) 331 if self.data['pk_patient'] is None: 332 self._PRW_patient.person = None 333 else: 334 self._PRW_patient.person = gmPerson.cPerson(aPK_obj = self.data['pk_patient']) 335 336 self._PRW_due.SetText(data = self.data['due_date']) 337 self._PRW_expiry.SetText(data = self.data['expiry_date']) 338 339 self._RBTN_normal.SetValue(False) 340 self._RBTN_high.SetValue(False) 341 self._RBTN_low.SetValue(False) 342 { -1: self._RBTN_low, 343 0: self._RBTN_normal, 344 1: self._RBTN_high 345 }[self.data['importance']].SetValue(True) 346 347 self._TCTRL_subject.SetFocus()
348 #---------------------------------------------------------------- 349 # event handlers 350 #----------------------------------------------------------------
351 - def _on_active_patient_checked(self, event):
352 if self._CHBOX_active_patient.IsChecked(): 353 self._PRW_patient.Enable(False) 354 self._PRW_patient.person = None 355 else: 356 self._PRW_patient.Enable(True)
357 #----------------------------------------------------------------
358 - def _on_send_to_me_checked(self, event):
359 if self._CHBOX_send_to_me.IsChecked(): 360 self._PRW_receiver.Enable(False) 361 self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff']) 362 else: 363 self._PRW_receiver.Enable(True) 364 self._PRW_receiver.SetText(value = '', data = None)
365 366 #============================================================
367 -def edit_inbox_message(parent=None, message=None, single_entry=True):
368 369 if parent is None: 370 parent = wx.GetApp().GetTopWindow() 371 372 ea = cInboxMessageEAPnl(parent, -1) 373 ea.data = message 374 ea.mode = gmTools.coalesce(message, 'new', 'edit') 375 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry) 376 dlg.SetTitle(gmTools.coalesce(message, _('Adding new inbox message'), _('Editing inbox message'))) 377 if dlg.ShowModal() == wx.ID_OK: 378 dlg.Destroy() 379 return True 380 dlg.Destroy() 381 return False
382 383 #============================================================
384 -def manage_reminders(parent=None, patient=None):
385 386 if parent is None: 387 parent = wx.GetApp().GetTopWindow() 388 #------------------------------------------------------------ 389 def refresh(lctrl): 390 reminders = gmProviderInbox.get_reminders(pk_patient = patient) 391 items = [ [ 392 gmTools.bool2subst ( 393 r['is_overdue'], 394 _('overdue for %s'), 395 _('due in %s') 396 ) % gmDateTime.format_interval_medically(r['interval_due']), 397 r['comment'], 398 r['pk_inbox_message'] 399 ] for r in reminders ] 400 lctrl.set_string_items(items) 401 lctrl.set_data(reminders)
402 #------------------------------------------------------------ 403 return gmListWidgets.get_choices_from_list ( 404 parent = parent, 405 msg = None, 406 caption = _('Reminders for the current patient'), 407 columns = [ _('Status'), _('Subject'), '#' ], 408 single_selection = False, 409 can_return_empty = True, 410 ignore_OK_button = False, 411 refresh_callback = refresh 412 # edit_callback=None, 413 # new_callback=None, 414 # delete_callback=None, 415 # left_extra_button=None, 416 # middle_extra_button=None, 417 # right_extra_button=None 418 ) 419 420 #============================================================ 421 from Gnumed.wxGladeWidgets import wxgProviderInboxPnl 422
423 -class cProviderInboxPnl(wxgProviderInboxPnl.wxgProviderInboxPnl, gmRegetMixin.cRegetOnPaintMixin):
424 425 _item_handlers = {} 426 427 #--------------------------------------------------------
428 - def __init__(self, *args, **kwds):
429 430 wxgProviderInboxPnl.wxgProviderInboxPnl.__init__(self, *args, **kwds) 431 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 432 433 self.provider = gmStaff.gmCurrentProvider() 434 self.__init_ui() 435 436 cProviderInboxPnl._item_handlers['clinical.review docs'] = self._goto_doc_review 437 cProviderInboxPnl._item_handlers['clinical.review results'] = self._goto_measurements_review 438 cProviderInboxPnl._item_handlers['clinical.review lab'] = self._goto_measurements_review 439 cProviderInboxPnl._item_handlers['clinical.review vaccs'] = self._goto_vaccination_review 440 441 self.__register_interests()
442 #-------------------------------------------------------- 443 # reget-on-paint API 444 #--------------------------------------------------------
445 - def _schedule_data_reget(self):
446 _log.debug('called by reget-on-paint mixin API') 447 gmRegetMixin.cRegetOnPaintMixin._schedule_data_reget(self)
448 #--------------------------------------------------------
449 - def _populate_with_data(self):
450 _log.debug('_populate_with_data() (after _schedule_data_reget ?)') 451 self.__populate_inbox() 452 return True
453 #-------------------------------------------------------- 454 # notebook plugin API 455 #--------------------------------------------------------
456 - def repopulate_ui(self):
457 _log.debug('called by notebook plugin API, skipping inbox loading') 458 #gmRegetMixin.cRegetOnPaintMixin.repopulate_ui(self) 459 return True
460 #--------------------------------------------------------
461 - def filter_by_active_patient(self):
462 self._CHBOX_active_patient.SetValue(True) 463 self._TXT_inbox_item_comment.SetValue('') 464 self.__populate_inbox()
465 #-------------------------------------------------------- 466 # internal helpers 467 #--------------------------------------------------------
468 - def __register_interests(self):
469 gmDispatcher.connect(signal = 'dem.message_inbox_mod_db', receiver = self._on_message_inbox_mod_db) 470 # FIXME: listen for results insertion/deletion 471 gmDispatcher.connect(signal = 'clin.reviewed_test_results_mod_db', receiver = self._on_results_mod_db) 472 gmDispatcher.connect(signal = 'dem.identity_mod_db', receiver = self._on_identity_mod_db) 473 gmDispatcher.connect(signal = 'blobs.doc_med_mod_db', receiver = self._on_doc_mod_db) 474 gmDispatcher.connect(signal = 'blobs.reviewed_doc_objs_mod_db', receiver = self._on_doc_obj_review_mod_db) 475 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self._on_post_patient_selection)
476 477 #--------------------------------------------------------
478 - def __init_ui(self):
479 self._LCTRL_provider_inbox.debug = 'provider inbox list' 480 481 self._LCTRL_provider_inbox.set_columns(['', _('Generated'), _('Status'), _('Patient'), _('Message'), _('Category - Type')]) 482 self._LCTRL_provider_inbox.searchable_columns = [2, 3, 4, 5] 483 self._LCTRL_provider_inbox.item_tooltip_callback = self._get_msg_tooltip 484 self._LCTRL_provider_inbox.extend_popup_menu_callback = self._extend_popup_menu 485 486 self.__update_greeting() 487 488 if gmPerson.gmCurrentPatient().connected: 489 self._CHBOX_active_patient.Enable()
490 491 #--------------------------------------------------------
492 - def __update_greeting(self, no_of_messages=None):
493 msg = _(' Inbox of %s %s%s') % ( 494 gmTools.coalesce ( 495 self.provider['title'], 496 gmPerson.map_gender2salutation(self.provider['gender']) 497 ), 498 self.provider['lastnames'], 499 gmTools.coalesce(no_of_messages, '.', _(': %s message(s)')) 500 ) 501 self._msg_welcome.SetLabel(msg)
502 503 #--------------------------------------------------------
504 - def __populate_inbox(self):
505 _log.debug('populating provider inbox') 506 507 # calculate constraints 508 pk_patient = None 509 if self._CHBOX_active_patient.IsChecked(): 510 _log.debug('restricting to active patient') 511 curr_pat = gmPerson.gmCurrentPatient() 512 if curr_pat.connected: 513 pk_patient = curr_pat.ID 514 515 include_without_provider = True 516 if self._CHBOX_active_provider.IsChecked(): 517 _log.debug('restricting to active provider directly') 518 include_without_provider = False 519 520 # get which messages to show 521 if self._RBTN_relevant_messages.GetValue(): 522 _log.debug('loading relevant messages') 523 self.__msgs = self.provider.inbox.get_relevant_messages ( 524 pk_patient = pk_patient, 525 include_without_provider = include_without_provider 526 ) 527 elif self._RBTN_all_messages.GetValue(): 528 _log.debug('loading all but expired messages') 529 self.__msgs = self.provider.inbox.get_messages ( 530 pk_patient = pk_patient, 531 include_without_provider = include_without_provider, 532 exclude_expired = True, 533 expired_only = False, 534 overdue_only = False, 535 unscheduled_only = False, 536 exclude_unscheduled = False 537 ) 538 elif self._RBTN_overdue_messages.GetValue(): 539 _log.debug('loading overdue messages only') 540 self.__msgs = self.provider.inbox.get_messages ( 541 pk_patient = pk_patient, 542 include_without_provider = include_without_provider, 543 exclude_expired = True, 544 expired_only = False, 545 overdue_only = True, 546 unscheduled_only = False, 547 exclude_unscheduled = True, 548 order_by = 'due_date, importance DESC, received_when DESC' 549 ) 550 elif self._RBTN_scheduled_messages.GetValue(): 551 _log.debug('loading scheduled messages only') 552 self.__msgs = self.provider.inbox.get_messages ( 553 pk_patient = pk_patient, 554 include_without_provider = include_without_provider, 555 exclude_expired = True, 556 expired_only = False, 557 overdue_only = False, 558 unscheduled_only = False, 559 exclude_unscheduled = True, 560 order_by = 'due_date, importance DESC, received_when DESC' 561 ) 562 elif self._RBTN_unscheduled_messages.GetValue(): 563 _log.debug('loading unscheduled messages only') 564 self.__msgs = self.provider.inbox.get_messages ( 565 pk_patient = pk_patient, 566 include_without_provider = include_without_provider, 567 exclude_expired = True, 568 expired_only = False, 569 overdue_only = False, 570 unscheduled_only = True, 571 exclude_unscheduled = False 572 ) 573 elif self._RBTN_expired_messages.GetValue(): 574 _log.debug('loading expired messages only') 575 self.__msgs = self.provider.inbox.get_messages ( 576 pk_patient = pk_patient, 577 include_without_provider = include_without_provider, 578 exclude_expired = False, 579 expired_only = True, 580 overdue_only = False, 581 unscheduled_only = False, 582 exclude_unscheduled = True, 583 order_by = 'expiry_date DESC, importance DESC, received_when DESC' 584 ) 585 586 _log.debug('total # of inbox msgs: %s', len(self.__msgs)) 587 588 items = [] 589 for m in self.__msgs: 590 item = [_indicator[m['importance']]] 591 item.append('%s: %s%s%s' % ( 592 gmDateTime.pydt_strftime(m['received_when'], '%Y-%m-%d'), 593 m['modified_by'], 594 gmTools.u_arrow2right, 595 gmTools.coalesce(m['provider'], _('all')) 596 )) 597 if m['due_date'] is None: 598 item.append('') 599 else: 600 if m['is_expired'] is True: 601 item.append(_('expired')) 602 else: 603 if m['is_overdue'] is True: 604 item.append(_('%s overdue') % gmDateTime.format_interval_medically(m['interval_due'])) 605 else: 606 item.append(_('due in %s') % gmDateTime.format_interval_medically(m['interval_due'])) 607 #pat 608 if m['pk_patient'] is None: 609 item.append('') 610 else: 611 item.append('%s, %s%s %s #%s' % ( 612 m['lastnames'], 613 m['firstnames'], 614 gmTools.coalesce(m['l10n_gender'], '', ' (%s)'), 615 gmDateTime.pydt_strftime(m['dob'], '%Y %b %d', none_str = ''), 616 m['pk_patient'] 617 )) 618 item.append(m['comment']) 619 item.append('%s - %s' % (m['l10n_category'], m['l10n_type'])) 620 items.append(item) 621 622 _log.debug('# of list items created from msgs: %s', len(items)) 623 self._LCTRL_provider_inbox.set_string_items(items = items) 624 self._LCTRL_provider_inbox.set_data(data = self.__msgs) 625 self._LCTRL_provider_inbox.set_column_widths() 626 self._TXT_inbox_item_comment.SetValue('') 627 self.__update_greeting(len(items))
628 #-------------------------------------------------------- 629 # event handlers 630 #--------------------------------------------------------
631 - def _on_results_mod_db(self):
632 _log.debug('reviewed_test_results_mod_db') 633 self._on_message_inbox_mod_db()
634 #--------------------------------------------------------
635 - def _on_identity_mod_db(self):
636 _log.debug('identity_mod_db') 637 self._on_message_inbox_mod_db()
638 #--------------------------------------------------------
640 _log.debug('doc_obj_review_mod_db') 641 self._on_message_inbox_mod_db()
642 #--------------------------------------------------------
643 - def _on_doc_mod_db(self):
644 _log.debug('doc_mod_db') 645 self._on_message_inbox_mod_db()
646 #--------------------------------------------------------
647 - def _on_message_inbox_mod_db(self, *args, **kwargs):
648 _log.debug('message_inbox_mod_db') 649 self._schedule_data_reget() 650 gmDispatcher.send(signal = 'request_user_attention', msg = _('Please check your GNUmed Inbox !'))
651 #--------------------------------------------------------
652 - def _on_post_patient_selection(self):
653 _log.debug('post_patient_selection') 654 self._CHBOX_active_patient.Enable() 655 self._schedule_data_reget()
656 #--------------------------------------------------------
657 - def _lst_item_activated(self, evt):
658 659 try: 660 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True) 661 except IndexError: 662 _log.exception('problem with provider inbox item data access') 663 gmGuiHelpers.gm_show_error ( 664 aTitle = _('handling provider inbox item'), 665 aMessage = _('There was a problem accessing the message data.') 666 ) 667 _log.debug('effecting inbox reload') 668 wx.CallAfter(self.__populate_inbox) 669 return False 670 671 if msg is None: 672 return 673 674 handler_key = '%s.%s' % (msg['category'], msg['type']) 675 try: 676 handle_item = cProviderInboxPnl._item_handlers[handler_key] 677 except KeyError: 678 if msg['pk_patient'] is None: 679 gmGuiHelpers.gm_show_warning ( 680 _('No double-click action pre-programmed into\n' 681 'GNUmed for message category and type:\n' 682 '\n' 683 ' [%s]\n' 684 ) % handler_key, 685 _('handling provider inbox item') 686 ) 687 return False 688 handle_item = self._goto_patient 689 690 if not handle_item(pk_context = msg['pk_context'], pk_patient = msg['pk_patient']): 691 _log.error('item handler returned <False>') 692 _log.error('handler key: [%s]', handler_key) 693 _log.error('message: %s', str(msg)) 694 return False 695 696 return True
697 #--------------------------------------------------------
698 - def _lst_item_focused(self, evt):
699 pass
700 #--------------------------------------------------------
701 - def _lst_item_selected(self, evt):
702 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True) 703 if msg is None: 704 return 705 706 if msg['data'] is None: 707 tmp = _('Message: %s') % msg['comment'] 708 else: 709 tmp = _('Message: %s\nData: %s') % (msg['comment'], msg['data']) 710 711 self._TXT_inbox_item_comment.SetValue(tmp)
712 #--------------------------------------------------------
713 - def _extend_popup_menu(self, menu=None):
714 tmp = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True) 715 if tmp is None: 716 return 717 self.__focussed_msg = tmp 718 719 if self.__focussed_msg['pk_patient'] is not None: 720 menu_item = menu.Append(-1, _('Activate patient')) 721 self.Bind(wx.EVT_MENU, self._on_goto_patient, menu_item) 722 723 if not self.__focussed_msg['is_virtual']: 724 menu_item = menu.Append(-1, _('Delete')) 725 self.Bind(wx.EVT_MENU, self._on_delete_focussed_msg, menu_item) 726 menu_item = menu.Append(-1, _('Edit')) 727 self.Bind(wx.EVT_MENU, self._on_edit_focussed_msg, menu_item)
728 729 # if self.__focussed_msg['pk_staff'] is not None: 730 # # - distribute to other providers 731 # item = menu.AppendItem(wx.MenuItem(menu, ID, _('Distribute'))) 732 # self.Bind(wx.EVT_MENU(menu, self._on_distribute_focussed_msg, item) 733 734 #--------------------------------------------------------
736 self._TXT_inbox_item_comment.SetValue('') 737 _log.debug('_on_message_range_radiobutton_selected') 738 self.__populate_inbox()
739 #--------------------------------------------------------
740 - def _on_active_patient_checkbox_ticked(self, event):
741 self._TXT_inbox_item_comment.SetValue('') 742 _log.debug('_on_active_patient_checkbox_ticked') 743 self.__populate_inbox()
744 #--------------------------------------------------------
745 - def _on_active_provider_checkbox_ticked(self, event):
746 self._TXT_inbox_item_comment.SetValue('') 747 _log.debug('_on_active_provider_checkbox_ticked') 748 self.__populate_inbox()
749 #--------------------------------------------------------
750 - def _on_add_button_pressed(self, event):
751 edit_inbox_message(parent = self, message = None, single_entry = False)
752 #--------------------------------------------------------
753 - def _get_msg_tooltip(self, msg):
754 return msg.format()
755 #-------------------------------------------------------- 756 # item handlers 757 #--------------------------------------------------------
758 - def _on_goto_patient(self, evt):
759 return self._goto_patient(pk_patient = self.__focussed_msg['pk_patient'])
760 #--------------------------------------------------------
761 - def _on_delete_focussed_msg(self, evt):
762 if self.__focussed_msg['is_virtual']: 763 gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True) 764 return False 765 766 # if not "to" current provider, then don't delete 767 if self.__focussed_msg['pk_staff'] != gmStaff.gmCurrentProvider()['pk_staff']: 768 gmDispatcher.send(signal = 'statustext', msg = _('This message can only be deleted by [%s].') % self.__focussed_msg['provider'], beep = True) 769 return False 770 771 pk_patient = self.__focussed_msg['pk_patient'] 772 if pk_patient is not None: 773 emr = gmClinicalRecord.cClinicalRecord(aPKey = pk_patient) 774 epi = emr.add_episode(episode_name = 'administrative', is_open = False) 775 soap_cat = gmTools.bool2subst ( 776 (self.__focussed_msg['category'] == 'clinical'), 777 'u', 778 None 779 ) 780 narr = _('Deleted inbox message:\n%s') % self.__focussed_msg.format(with_patient = False) 781 emr.add_clin_narrative(note = narr, soap_cat = soap_cat, episode = epi) 782 gmDispatcher.send(signal = 'statustext', msg = _('Recorded deletion of inbox message in EMR.'), beep = False) 783 784 if not self.provider.inbox.delete_message(self.__focussed_msg['pk_inbox_message']): 785 gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.')) 786 return False 787 788 return True
789 #--------------------------------------------------------
790 - def _on_edit_focussed_msg(self, evt):
791 if self.__focussed_msg['is_virtual']: 792 gmDispatcher.send(signal = 'statustext', msg = _('This message cannot be edited because it is virtual.')) 793 return False 794 edit_inbox_message(parent = self, message = self.__focussed_msg, single_entry = True) 795 return True
796 #--------------------------------------------------------
797 - def _on_distribute_focussed_msg(self, evt):
798 if self.__focussed_msg['pk_staff'] is None: 799 gmDispatcher.send(signal = 'statustext', msg = _('This message is already visible to all providers.')) 800 return False 801 print("now distributing") 802 return True
803 #--------------------------------------------------------
804 - def _goto_patient(self, pk_context=None, pk_patient=None):
805 806 wx.BeginBusyCursor() 807 808 msg = _('There is a message about patient [%s].\n\n' 809 'However, I cannot find that\n' 810 'patient in the GNUmed database.' 811 ) % pk_patient 812 813 try: 814 pat = gmPerson.cPerson(aPK_obj = pk_patient) 815 except gmExceptions.ConstructorError: 816 wx.EndBusyCursor() 817 _log.exception('patient [%s] not found', pk_patient) 818 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 819 return False 820 except: 821 wx.EndBusyCursor() 822 raise 823 824 success = set_active_patient(patient = pat) 825 826 wx.EndBusyCursor() 827 828 if not success: 829 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 830 return False 831 832 return True
833 #--------------------------------------------------------
834 - def _goto_doc_review(self, pk_context=None, pk_patient=None):
835 836 msg = _('Supposedly there are unreviewed documents\n' 837 'for patient [%s]. However, I cannot find\n' 838 'that patient in the GNUmed database.' 839 ) % pk_patient 840 841 wx.BeginBusyCursor() 842 843 try: 844 pat = gmPerson.cPerson(aPK_obj = pk_patient) 845 except gmExceptions.ConstructorError: 846 wx.EndBusyCursor() 847 _log.exception('patient [%s] not found', pk_patient) 848 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 849 return False 850 851 success = set_active_patient(patient = pat) 852 853 wx.EndBusyCursor() 854 855 if not success: 856 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 857 return False 858 859 gmDispatcher.send(signal = 'display_widget', name = 'gmShowMedDocs', sort_mode = 'review') 860 return True
861 #--------------------------------------------------------
862 - def _goto_measurements_review(self, pk_context=None, pk_patient=None):
863 864 msg = _('Supposedly there are unreviewed results\n' 865 'for patient [%s]. However, I cannot find\n' 866 'that patient in the GNUmed database.' 867 ) % pk_patient 868 869 wx.BeginBusyCursor() 870 871 try: 872 pat = gmPerson.cPerson(aPK_obj = pk_patient) 873 except gmExceptions.ConstructorError: 874 wx.EndBusyCursor() 875 _log.exception('patient [%s] not found', pk_patient) 876 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 877 return False 878 879 success = set_active_patient(patient = pat) 880 881 wx.EndBusyCursor() 882 883 if not success: 884 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 885 return False 886 887 gmDispatcher.send(signal = 'display_widget', name = 'gmMeasurementsGridPlugin') 888 return True
889 #--------------------------------------------------------
890 - def _goto_vaccination_review(self, pk_context=None, pk_patient=None):
891 892 msg = _('Supposedly there are conflicting vaccinations\n' 893 'for patient [%s]. However, I cannot find\n' 894 'that patient in the GNUmed database.' 895 ) % pk_patient 896 897 wx.BeginBusyCursor() 898 899 try: 900 pat = gmPerson.cPerson(aPK_obj = pk_patient) 901 except gmExceptions.ConstructorError: 902 wx.EndBusyCursor() 903 _log.exception('patient [%s] not found', pk_patient) 904 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 905 return False 906 907 success = set_active_patient(patient = pat) 908 909 wx.EndBusyCursor() 910 911 if not success: 912 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item')) 913 return False 914 915 wx.CallAfter(gmVaccWidgets.manage_vaccinations) 916 917 return True
918 919 #============================================================ 920 if __name__ == '__main__': 921 922 if len(sys.argv) < 2: 923 sys.exit() 924 925 if sys.argv[1] != 'test': 926 sys.exit() 927 928 gmI18N.activate_locale() 929 gmI18N.install_domain(domain = 'gnumed') 930
931 - def test_message_inbox():
932 app = wx.PyWidgetTester(size = (800, 600)) 933 app.SetWidget(cProviderInboxPnl, -1) 934 app.MainLoop()
935
936 - def test_msg_ea():
937 app = wx.PyWidgetTester(size = (800, 600)) 938 app.SetWidget(cInboxMessageEAPnl, -1) 939 app.MainLoop()
940 941 942 #test_message_inbox() 943 test_msg_ea() 944 945 #============================================================ 946