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