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

Source Code for Module Gnumed.wxpython.gmWaitingListWidgets

  1  """GNUmed data pack related widgets.""" 
  2  #================================================================ 
  3  __author__ = 'karsten.hilbert@gmx.net' 
  4  __license__ = 'GPL v2 or later (details at http://www.gnu.org)' 
  5   
  6  # stdlib 
  7  import logging 
  8  import sys 
  9   
 10   
 11  # 3rd party 
 12  import wx 
 13   
 14   
 15  # GNUmed 
 16  if __name__ == '__main__': 
 17          sys.path.insert(0, '../../') 
 18   
 19  from Gnumed.pycommon import gmDispatcher 
 20  from Gnumed.pycommon import gmTools 
 21  from Gnumed.pycommon import gmMatchProvider 
 22  from Gnumed.pycommon import gmI18N 
 23   
 24  from Gnumed.business import gmSurgery 
 25  from Gnumed.business import gmPerson 
 26   
 27  from Gnumed.wxpython import gmEditArea 
 28  from Gnumed.wxpython import gmPhraseWheel 
 29  from Gnumed.wxpython import gmRegetMixin 
 30  from Gnumed.wxpython import gmPatSearchWidgets 
 31  from Gnumed.wxpython import gmGuiHelpers 
 32   
 33   
 34  _log = logging.getLogger('gm.ui') 
 35  #============================================================ 
 36  # waiting list widgets 
 37  #============================================================ 
38 -class cWaitingZonePhraseWheel(gmPhraseWheel.cPhraseWheel):
39
40 - def __init__(self, *args, **kwargs):
41 42 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 43 44 mp = gmMatchProvider.cMatchProvider_FixedList(aSeq = []) 45 mp.setThresholds(1, 2, 2) 46 self.matcher = mp 47 self.selection_only = False
48 49 #--------------------------------------------------------
50 - def update_matcher(self, items):
51 self.matcher.set_items([ {'data': i, 'list_label': i, 'field_label': i, 'weight': 1} for i in items ])
52 53 #============================================================ 54 from Gnumed.wxGladeWidgets import wxgWaitingListEntryEditAreaPnl 55
56 -class cWaitingListEntryEditAreaPnl(wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
57
58 - def __init__ (self, *args, **kwargs):
59 60 try: 61 self.patient = kwargs['patient'] 62 del kwargs['patient'] 63 except KeyError: 64 self.patient = None 65 66 try: 67 data = kwargs['entry'] 68 del kwargs['entry'] 69 except KeyError: 70 data = None 71 72 wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl.__init__(self, *args, **kwargs) 73 gmEditArea.cGenericEditAreaMixin.__init__(self) 74 75 if data is None: 76 self.mode = 'new' 77 else: 78 self.data = data 79 self.mode = 'edit' 80 81 praxis = gmSurgery.gmCurrentPractice() 82 pats = praxis.waiting_list_patients 83 zones = {} 84 zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ]) 85 self._PRW_zone.update_matcher(items = zones.keys())
86 #-------------------------------------------------------- 87 # edit area mixin API 88 #--------------------------------------------------------
89 - def _refresh_as_new(self):
90 if self.patient is None: 91 self._PRW_patient.person = None 92 self._PRW_patient.Enable(True) 93 self._PRW_patient.SetFocus() 94 else: 95 self._PRW_patient.person = self.patient 96 self._PRW_patient.Enable(False) 97 self._TCTRL_comment.SetFocus() 98 self._PRW_patient._display_name() 99 100 self._TCTRL_comment.SetValue(u'') 101 self._PRW_zone.SetValue(u'') 102 self._SPCTRL_urgency.SetValue(0)
103 #--------------------------------------------------------
104 - def _refresh_from_existing(self):
105 self._PRW_patient.person = gmPerson.cIdentity(aPK_obj = self.data['pk_identity']) 106 self._PRW_patient.Enable(False) 107 self._PRW_patient._display_name() 108 109 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u'')) 110 self._PRW_zone.SetValue(gmTools.coalesce(self.data['waiting_zone'], u'')) 111 self._SPCTRL_urgency.SetValue(self.data['urgency']) 112 113 self._TCTRL_comment.SetFocus()
114 #--------------------------------------------------------
115 - def _valid_for_save(self):
116 validity = True 117 118 self.display_tctrl_as_valid(tctrl = self._PRW_patient, valid = (self._PRW_patient.person is not None)) 119 validity = (self._PRW_patient.person is not None) 120 121 if validity is False: 122 gmDispatcher.send(signal = 'statustext', msg = _('Cannot add to waiting list. Missing essential input.')) 123 124 return validity
125 #----------------------------------------------------------------
126 - def _save_as_new(self):
127 # FIXME: filter out dupes 128 self._PRW_patient.person.put_on_waiting_list ( 129 urgency = self._SPCTRL_urgency.GetValue(), 130 comment = gmTools.none_if(self._TCTRL_comment.GetValue().strip(), u''), 131 zone = gmTools.none_if(self._PRW_zone.GetValue().strip(), u'') 132 ) 133 # dummy: 134 self.data = {'pk_identity': self._PRW_patient.person.ID, 'comment': None, 'waiting_zone': None, 'urgency': 0} 135 return True
136 #----------------------------------------------------------------
137 - def _save_as_update(self):
138 gmSurgery.gmCurrentPractice().update_in_waiting_list ( 139 pk = self.data['pk_waiting_list'], 140 urgency = self._SPCTRL_urgency.GetValue(), 141 comment = self._TCTRL_comment.GetValue().strip(), 142 zone = self._PRW_zone.GetValue().strip() 143 ) 144 return True
145 #============================================================ 146 from Gnumed.wxGladeWidgets import wxgWaitingListPnl 147
148 -class cWaitingListPnl(wxgWaitingListPnl.wxgWaitingListPnl, gmRegetMixin.cRegetOnPaintMixin):
149
150 - def __init__ (self, *args, **kwargs):
151 152 wxgWaitingListPnl.wxgWaitingListPnl.__init__(self, *args, **kwargs) 153 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 154 155 self.__current_zone = None 156 self.__last_patient = None 157 self.__last_comment = None 158 159 self.__init_ui() 160 self.__register_events()
161 #-------------------------------------------------------- 162 # interal helpers 163 #--------------------------------------------------------
164 - def __init_ui(self):
165 self._LCTRL_patients.set_columns ([ 166 _('Zone'), 167 _('Urgency'), 168 #' ! ', 169 _('Waiting time'), 170 _('Patient'), 171 _('Born'), 172 _('Comment') 173 ]) 174 self._LCTRL_patients.set_column_widths(widths = [wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE_USEHEADER, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 175 self._LCTRL_patients.item_tooltip_callback = self._on_get_list_tooltip 176 self._PRW_zone.add_callback_on_selection(callback = self._on_zone_selected) 177 self._PRW_zone.add_callback_on_lose_focus(callback = self._on_zone_selected)
178 #--------------------------------------------------------
179 - def _check_RFE(self):
180 """ 181 This gets called when a patient has been activated, but 182 only when the waiting list is actually in use (that is, 183 the plugin is loaded 184 """ 185 pat = gmPerson.gmCurrentPatient() 186 enc = pat.emr.active_encounter 187 if gmTools.coalesce(enc['reason_for_encounter'], u'').strip() != u'': 188 return 189 entries = pat.waiting_list_entries 190 if len(entries) == 0: 191 if self.__last_patient is None: 192 return 193 if self.__last_patient != pat.ID: 194 return 195 rfe = self.__last_comment 196 else: 197 entry = entries[0] 198 if gmTools.coalesce(entry['comment'], u'').strip() == u'': 199 return 200 rfe = entry['comment'].strip() 201 enc['reason_for_encounter'] = rfe 202 enc.save() 203 self.__last_patient = None
204 #--------------------------------------------------------
205 - def _on_get_list_tooltip(self, entry):
206 207 dob = gmTools.coalesce ( 208 gmTools.coalesce ( 209 entry['dob'], 210 u'', 211 function_initial = ('strftime', '%d %b %Y') 212 ), 213 u'', 214 u' (%s)', 215 function_initial = ('decode', gmI18N.get_encoding()) 216 ) 217 218 tt = _( 219 '%s patients are waiting.\n' 220 '\n' 221 'Doubleclick to activate (entry will stay in list).' 222 ) % self._LCTRL_patients.GetItemCount() 223 224 tt += _( 225 '\n' 226 '%s\n' 227 'Patient: %s%s\n' 228 '%s' 229 'Urgency: %s\n' 230 'Time: %s\n' 231 '%s' 232 ) % ( 233 gmTools.u_box_horiz_single * 50, 234 u'%s, %s (%s)' % (entry['lastnames'], entry['firstnames'], entry['l10n_gender']), 235 dob, 236 gmTools.coalesce(entry['waiting_zone'], u'', _('Zone: %s\n')), 237 entry['urgency'], 238 entry['waiting_time_formatted'].replace(u'00 ', u'', 1).replace('00:', u'').lstrip('0'), 239 gmTools.coalesce(entry['comment'], u'', u'\n%s') 240 ) 241 242 return tt
243 #--------------------------------------------------------
244 - def __register_events(self):
245 gmDispatcher.connect(signal = u'waiting_list_generic_mod_db', receiver = self._on_waiting_list_modified) 246 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
247 #--------------------------------------------------------
248 - def __refresh_waiting_list(self):
249 self.__last_patient = None 250 251 praxis = gmSurgery.gmCurrentPractice() 252 pats = praxis.waiting_list_patients 253 254 # set matcher to all zones currently in use 255 zones = {} 256 zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ]) 257 self._PRW_zone.update_matcher(items = zones.keys()) 258 259 # filter patient list by zone and set waiting list 260 self.__current_zone = self._PRW_zone.GetValue().strip() 261 if self.__current_zone == u'': 262 pats = [ p for p in pats ] 263 else: 264 pats = [ p for p in pats if p['waiting_zone'] == self.__current_zone ] 265 266 old_pks = [ d['pk_waiting_list'] for d in self._LCTRL_patients.get_selected_item_data() ] 267 self._LCTRL_patients.set_string_items ( 268 [ [ 269 gmTools.coalesce(p['waiting_zone'], u''), 270 p['urgency'], 271 p['waiting_time_formatted'].replace(u'00 ', u'', 1).replace('00:', u'').lstrip('0'), 272 u'%s, %s (%s)' % (p['lastnames'], p['firstnames'], p['l10n_gender']), 273 gmTools.coalesce ( 274 gmTools.coalesce ( 275 p['dob'], 276 u'', 277 function_initial = ('strftime', '%d %b %Y') 278 ), 279 u'', 280 function_initial = ('decode', gmI18N.get_encoding()) 281 ), 282 gmTools.coalesce(p['comment'], u'').split('\n')[0] 283 ] for p in pats ] 284 ) 285 self._LCTRL_patients.set_column_widths() 286 self._LCTRL_patients.set_data(pats) 287 new_selections = [] 288 new_pks = [ p['pk_waiting_list'] for p in pats ] 289 for old_pk in old_pks: 290 if old_pk in new_pks: 291 new_selections.append(new_pks.index(old_pk)) 292 self._LCTRL_patients.selections = new_selections 293 self._LCTRL_patients.Refresh() 294 295 self._LBL_no_of_patients.SetLabel(_('(%s patients)') % len(pats)) 296 297 if len(pats) == 0: 298 self._BTN_activate.Enable(False) 299 self._BTN_activateplus.Enable(False) 300 self._BTN_remove.Enable(False) 301 self._BTN_edit.Enable(False) 302 self._BTN_up.Enable(False) 303 self._BTN_down.Enable(False) 304 else: 305 self._BTN_activate.Enable(True) 306 self._BTN_activateplus.Enable(True) 307 self._BTN_remove.Enable(True) 308 self._BTN_edit.Enable(True) 309 if len(pats) > 1: 310 self._BTN_up.Enable(True) 311 self._BTN_down.Enable(True)
312 #-------------------------------------------------------- 313 # event handlers 314 #--------------------------------------------------------
315 - def _on_zone_selected(self, zone=None):
316 self.__last_patient = None 317 if self.__current_zone == self._PRW_zone.GetValue().strip(): 318 return True 319 wx.CallAfter(self.__refresh_waiting_list) 320 return True
321 #--------------------------------------------------------
322 - def _on_waiting_list_modified(self, *args, **kwargs):
323 self.__last_patient = None 324 wx.CallAfter(self._schedule_data_reget)
325 #--------------------------------------------------------
326 - def _on_post_patient_selection(self, *args, **kwargs):
327 wx.CallAfter(self._check_RFE)
328 #--------------------------------------------------------
329 - def _on_list_item_activated(self, evt):
330 self.__last_patient = None 331 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 332 if item is None: 333 return 334 pat = gmPerson.cIdentity(aPK_obj = item['pk_identity']) 335 wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
336 #--------------------------------------------------------
337 - def _on_activate_button_pressed(self, evt):
338 self.__last_patient = None 339 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 340 if item is None: 341 return 342 pat = gmPerson.cIdentity(aPK_obj = item['pk_identity']) 343 wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
344 #--------------------------------------------------------
345 - def _on_activateplus_button_pressed(self, evt):
346 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 347 if item is None: 348 return 349 pat = gmPerson.cIdentity(aPK_obj = item['pk_identity']) 350 self.__last_patient = item['pk_identity'] 351 self.__last_comment = gmTools.coalesce(item['comment'], u'').strip() 352 gmSurgery.gmCurrentPractice().remove_from_waiting_list(pk = item['pk_waiting_list']) 353 wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
354 #--------------------------------------------------------
355 - def _on_add_patient_button_pressed(self, evt):
356 self.__last_patient = None 357 curr_pat = gmPerson.gmCurrentPatient() 358 if not curr_pat.connected: 359 gmDispatcher.send(signal = 'statustext', msg = _('Cannot add waiting list entry: No patient selected.'), beep = True) 360 return 361 ea = cWaitingListEntryEditAreaPnl(self, -1, patient = curr_pat) 362 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True) 363 dlg.ShowModal() 364 dlg.Destroy()
365 #--------------------------------------------------------
366 - def _on_edit_button_pressed(self, event):
367 self.__last_patient = None 368 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 369 if item is None: 370 return 371 ea = cWaitingListEntryEditAreaPnl(self, -1, entry = item) 372 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True) 373 dlg.ShowModal() 374 dlg.Destroy()
375 #--------------------------------------------------------
376 - def _on_remove_button_pressed(self, evt):
377 self.__last_patient = None 378 item = self._LCTRL_patients.get_selected_item_data(only_one = True) 379 if item is None: 380 return 381 cmt = gmTools.coalesce(item['comment'], u'').split('\n')[0].strip()[:40] 382 if cmt != u'': 383 cmt += u'\n' 384 question = _( 385 'Are you sure you want to remove\n' 386 '\n' 387 ' %s, %s (%s)\n' 388 ' born: %s\n' 389 ' %s' 390 '\n' 391 'from the waiting list ?' 392 ) % ( 393 item['lastnames'], 394 item['firstnames'], 395 item['l10n_gender'], 396 gmTools.coalesce ( 397 gmTools.coalesce ( 398 item['dob'], 399 u'', 400 function_initial = ('strftime', '%d %b %Y') 401 ), 402 u'', 403 function_initial = ('decode', gmI18N.get_encoding()) 404 ), 405 cmt 406 ) 407 do_delete = gmGuiHelpers.gm_show_question ( 408 title = _('Delete waiting list entry'), 409 question = question 410 ) 411 if not do_delete: 412 return 413 gmSurgery.gmCurrentPractice().remove_from_waiting_list(pk = item['pk_waiting_list'])
414 #--------------------------------------------------------
415 - def _on_up_button_pressed(self, evt):
416 self.__last_patient = None 417 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 418 if item is None: 419 return 420 gmSurgery.gmCurrentPractice().raise_in_waiting_list(current_position = item['list_position'])
421 #--------------------------------------------------------
422 - def _on_down_button_pressed(self, evt):
423 self.__last_patient = None 424 item = self._LCTRL_patients.get_selected_item_data(only_one=True) 425 if item is None: 426 return 427 gmSurgery.gmCurrentPractice().lower_in_waiting_list(current_position = item['list_position'])
428 #-------------------------------------------------------- 429 # edit 430 #-------------------------------------------------------- 431 # reget-on-paint API 432 #--------------------------------------------------------
433 - def _populate_with_data(self):
434 self.__refresh_waiting_list() 435 return True
436 #================================================================ 437 # main 438 #---------------------------------------------------------------- 439 if __name__ == '__main__': 440 441 if len(sys.argv) < 2: 442 sys.exit() 443 444 if sys.argv[1] != 'test': 445 sys.exit() 446 447 gmI18N.activate_locale() 448 gmI18N.install_domain() 449 450 #-------------------------------------------------------- 451 # def test_generic_codes_prw(): 452 # gmPG2.get_connection() 453 # app = wx.PyWidgetTester(size = (500, 40)) 454 # pw = cGenericCodesPhraseWheel(app.frame, -1) 455 # #pw.set_context(context = u'zip', val = u'04318') 456 # app.frame.Show(True) 457 # app.MainLoop() 458 # #-------------------------------------------------------- 459 # test_generic_codes_prw() 460 461 app = wx.PyWidgetTester(size = (200, 40)) 462 app.SetWidget(cWaitingListPnl, -1) 463 app.MainLoop() 464 465 #================================================================ 466