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

Source Code for Module Gnumed.wxpython.gmVaccWidgets

   1  """GNUmed immunisation/vaccination widgets. 
   2   
   3  Modelled after Richard Terry's design document. 
   4   
   5  copyright: authors 
   6  """ 
   7  #====================================================================== 
   8  __version__ = "$Revision: 1.36 $" 
   9  __author__ = "R.Terry, S.J.Tan, K.Hilbert" 
  10  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
  11   
  12  import sys, time, logging 
  13   
  14   
  15  import wx 
  16   
  17   
  18  if __name__ == '__main__': 
  19          sys.path.insert(0, '../../') 
  20  from Gnumed.pycommon import gmDispatcher, gmMatchProvider, gmTools, gmI18N 
  21  from Gnumed.pycommon import gmCfg, gmDateTime, gmNetworkTools 
  22  from Gnumed.business import gmPerson, gmVaccination, gmSurgery 
  23  from Gnumed.wxpython import gmPhraseWheel, gmTerryGuiParts, gmRegetMixin, gmGuiHelpers 
  24  from Gnumed.wxpython import gmEditArea, gmListWidgets 
  25   
  26   
  27  _log = logging.getLogger('gm.vaccination') 
  28  _log.info(__version__) 
  29   
  30  #====================================================================== 
  31  # vaccination indication related widgets 
  32  #---------------------------------------------------------------------- 
33 -def manage_vaccination_indications(parent=None):
34 35 if parent is None: 36 parent = wx.GetApp().GetTopWindow() 37 #------------------------------------------------------------ 38 def refresh(lctrl): 39 inds = gmVaccination.get_indications(order_by = 'description') 40 41 items = [ [ 42 i['description'], 43 gmTools.coalesce ( 44 i['atcs_single_indication'], 45 u'', 46 u'%s' 47 ), 48 gmTools.coalesce ( 49 i['atcs_combi_indication'], 50 u'', 51 u'%s' 52 ), 53 u'%s' % i['id'] 54 ] for i in inds ] 55 56 lctrl.set_string_items(items) 57 lctrl.set_data(inds)
58 #------------------------------------------------------------ 59 gmListWidgets.get_choices_from_list ( 60 parent = parent, 61 msg = _('\nConditions preventable by vaccination as currently known to GNUmed.\n'), 62 caption = _('Showing vaccination preventable conditions.'), 63 columns = [ _('Condition'), _('ATCs: single-condition vaccines'), _('ATCs: multi-condition vaccines'), u'#' ], 64 single_selection = True, 65 refresh_callback = refresh 66 ) 67 #---------------------------------------------------------------------- 68 from Gnumed.wxGladeWidgets import wxgVaccinationIndicationsPnl 69
70 -class cVaccinationIndicationsPnl(wxgVaccinationIndicationsPnl.wxgVaccinationIndicationsPnl):
71
72 - def __init__(self, *args, **kwargs):
73 74 wxgVaccinationIndicationsPnl.wxgVaccinationIndicationsPnl.__init__(self, *args, **kwargs) 75 76 self.__indication2field = { 77 u'coxiella burnetii (Q fever)': self._CHBOX_coxq, 78 u'salmonella typhi (typhoid)': self._CHBOX_typhoid, 79 u'varicella (chickenpox, shingles)': self._CHBOX_varicella, 80 u'influenza (seasonal)': self._CHBOX_influenza, 81 u'bacillus anthracis (Anthrax)': self._CHBOX_anthrax, 82 u'human papillomavirus': self._CHBOX_hpv, 83 u'rotavirus': self._CHBOX_rota, 84 u'tuberculosis': self._CHBOX_tuberculosis, 85 u'variola virus (smallpox)': self._CHBOX_smallpox, 86 u'influenza (H1N1)': self._CHBOX_h1n1, 87 u'cholera': self._CHBOX_cholera, 88 u'diphtheria': self._CHBOX_diphtheria, 89 u'haemophilus influenzae b': self._CHBOX_hib, 90 u'hepatitis A': self._CHBOX_hepA, 91 u'hepatitis B': self._CHBOX_hepB, 92 u'japanese B encephalitis': self._CHBOX_japanese, 93 u'measles': self._CHBOX_measles, 94 u'meningococcus A': self._CHBOX_menA, 95 u'meningococcus C': self._CHBOX_menC, 96 u'meningococcus W': self._CHBOX_menW, 97 u'meningococcus Y': self._CHBOX_menY, 98 u'mumps': self._CHBOX_mumps, 99 u'pertussis': self._CHBOX_pertussis, 100 u'pneumococcus': self._CHBOX_pneumococcus, 101 u'poliomyelitis': self._CHBOX_polio, 102 u'rabies': self._CHBOX_rabies, 103 u'rubella': self._CHBOX_rubella, 104 u'tetanus': self._CHBOX_tetanus, 105 u'tick-borne meningoencephalitis': self._CHBOX_fsme, 106 u'yellow fever': self._CHBOX_yellow_fever, 107 u'yersinia pestis': self._CHBOX_yersinia_pestis 108 }
109 #------------------------------------------------------------------
110 - def enable_all(self):
111 for field in self.__dict__.keys(): 112 if field.startswith('_CHBOX_'): 113 self.__dict__[field].Enable() 114 self.Enable()
115 #------------------------------------------------------------------
116 - def disable_all(self):
117 for field in self.__dict__.keys(): 118 if field.startswith('_CHBOX_'): 119 self.__dict__[field].Disable() 120 self.Disable()
121 #------------------------------------------------------------------
122 - def clear_all(self):
123 for field in self.__dict__.keys(): 124 if field.startswith('_CHBOX_'): 125 self.__dict__[field].SetValue(False)
126 #------------------------------------------------------------------
127 - def select(self, indications=None):
128 for indication in indications: 129 try: 130 self.__indication2field[indication].SetValue(True) 131 except KeyError: 132 pass
133 #------------------------------------------------------------------
134 - def _get_selected_indications(self):
135 indications = [] 136 for indication in self.__indication2field.keys(): 137 if self.__indication2field[indication].IsChecked(): 138 indications.append(indication) 139 return indications
140 141 selected_indications = property(_get_selected_indications, lambda x:x) 142 #------------------------------------------------------------------
143 - def _get_has_selection(self):
144 for indication in self.__indication2field.keys(): 145 if self.__indication2field[indication].IsChecked(): 146 return True 147 return False
148 149 has_selection = property(_get_has_selection, lambda x:x)
150 151 #====================================================================== 152 # vaccines related widgets 153 #----------------------------------------------------------------------
154 -def edit_vaccine(parent=None, vaccine=None, single_entry=True):
155 ea = cVaccineEAPnl(parent = parent, id = -1) 156 ea.data = vaccine 157 ea.mode = gmTools.coalesce(vaccine, 'new', 'edit') 158 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 159 dlg.SetTitle(gmTools.coalesce(vaccine, _('Adding new vaccine'), _('Editing vaccine'))) 160 if dlg.ShowModal() == wx.ID_OK: 161 dlg.Destroy() 162 return True 163 dlg.Destroy() 164 return False
165 #----------------------------------------------------------------------
166 -def manage_vaccines(parent=None):
167 168 if parent is None: 169 parent = wx.GetApp().GetTopWindow() 170 #------------------------------------------------------------ 171 def delete(vaccine=None): 172 deleted = gmVaccination.delete_vaccine(vaccine = vaccine['pk_vaccine']) 173 if deleted: 174 return True 175 176 gmGuiHelpers.gm_show_info ( 177 _( 178 'Cannot delete vaccine\n' 179 '\n' 180 ' %s - %s (#%s)\n' 181 '\n' 182 'It is probably documented in a vaccination.' 183 ) % ( 184 vaccine['vaccine'], 185 vaccine['preparation'], 186 vaccine['pk_vaccine'] 187 ), 188 _('Deleting vaccine') 189 ) 190 191 return False
192 #------------------------------------------------------------ 193 def edit(vaccine=None): 194 return edit_vaccine(parent = parent, vaccine = vaccine, single_entry = True) 195 #------------------------------------------------------------ 196 def refresh(lctrl): 197 vaccines = gmVaccination.get_vaccines(order_by = 'vaccine') 198 199 items = [ [ 200 u'%s' % v['pk_brand'], 201 u'%s%s' % ( 202 v['vaccine'], 203 gmTools.bool2subst ( 204 v['is_fake_vaccine'], 205 u' (%s)' % _('fake'), 206 u'' 207 ) 208 ), 209 v['preparation'], 210 #u'%s (%s)' % (v['route_abbreviation'], v['route_description']), 211 #gmTools.bool2subst(v['is_live'], gmTools.u_checkmark_thin, u'', u'?'), 212 gmTools.coalesce(v['atc_code'], u''), 213 u'%s%s' % ( 214 gmTools.coalesce(v['min_age'], u'?'), 215 gmTools.coalesce(v['max_age'], u'?', u' - %s'), 216 ), 217 gmTools.coalesce(v['comment'], u'') 218 ] for v in vaccines ] 219 lctrl.set_string_items(items) 220 lctrl.set_data(vaccines) 221 #------------------------------------------------------------ 222 gmListWidgets.get_choices_from_list ( 223 parent = parent, 224 msg = _('\nThe vaccines currently known to GNUmed.\n'), 225 caption = _('Showing vaccines.'), 226 #columns = [ u'#', _('Brand'), _('Preparation'), _(u'Route'), _('Live'), _('ATC'), _('Age range'), _('Comment') ], 227 columns = [ u'#', _('Brand'), _('Preparation'), _('ATC'), _('Age range'), _('Comment') ], 228 single_selection = True, 229 refresh_callback = refresh, 230 edit_callback = edit, 231 new_callback = edit, 232 delete_callback = delete 233 ) 234 #----------------------------------------------------------------------
235 -class cBatchNoPhraseWheel(gmPhraseWheel.cPhraseWheel):
236
237 - def __init__(self, *args, **kwargs):
238 239 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 240 241 context = { 242 u'ctxt_vaccine': { 243 u'where_part': u'AND pk_vaccine = %(pk_vaccine)s', 244 u'placeholder': u'pk_vaccine' 245 } 246 } 247 248 query = u""" 249 SELECT data, field_label, list_label FROM ( 250 251 SELECT distinct on (field_label) 252 data, 253 field_label, 254 list_label, 255 rank 256 FROM (( 257 -- batch_no by vaccine 258 SELECT 259 batch_no AS data, 260 batch_no AS field_label, 261 batch_no || ' (' || vaccine || ')' AS list_label, 262 1 as rank 263 FROM 264 clin.v_pat_vaccinations 265 WHERE 266 batch_no %(fragment_condition)s 267 %(ctxt_vaccine)s 268 ) UNION ALL ( 269 -- batch_no for any vaccine 270 SELECT 271 batch_no AS data, 272 batch_no AS field_label, 273 batch_no || ' (' || vaccine || ')' AS list_label, 274 2 AS rank 275 FROM 276 clin.v_pat_vaccinations 277 WHERE 278 batch_no %(fragment_condition)s 279 ) 280 281 ) AS matching_batch_nos 282 283 ) as unique_matches 284 285 ORDER BY rank, list_label 286 LIMIT 25 287 """ 288 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query, context = context) 289 mp.setThresholds(1, 2, 3) 290 self.matcher = mp 291 292 self.unset_context(context = u'pk_vaccine') 293 self.SetToolTipString(_('Enter or select the batch/lot number of the vaccine used.')) 294 self.selection_only = False
295 #----------------------------------------------------------------------
296 -class cVaccinePhraseWheel(gmPhraseWheel.cPhraseWheel):
297
298 - def __init__(self, *args, **kwargs):
299 300 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 301 302 # consider ATCs in ref.branded_drug and vacc_indication 303 query = u""" 304 SELECT data, list_label, field_label FROM ( 305 306 SELECT DISTINCT ON (data) 307 data, 308 list_label, 309 field_label 310 FROM (( 311 -- fragment -> vaccine 312 SELECT 313 pk_vaccine AS data, 314 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')' AS list_label, 315 vaccine AS field_label 316 FROM 317 clin.v_vaccines 318 WHERE 319 vaccine %(fragment_condition)s 320 321 ) union all ( 322 323 -- fragment -> localized indication -> vaccines 324 SELECT 325 pk_vaccine AS data, 326 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')' AS list_label, 327 vaccine AS field_label 328 FROM 329 clin.v_indications4vaccine 330 WHERE 331 l10n_indication %(fragment_condition)s 332 333 ) union all ( 334 335 -- fragment -> indication -> vaccines 336 SELECT 337 pk_vaccine AS data, 338 vaccine || ' (' || array_to_string(indications, ', ') || ')' AS list_label, 339 vaccine AS field_label 340 FROM 341 clin.v_indications4vaccine 342 WHERE 343 indication %(fragment_condition)s 344 ) 345 ) AS distinct_total 346 347 ) AS total 348 349 ORDER by list_label 350 LIMIT 25 351 """ 352 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query) 353 mp.setThresholds(1, 2, 3) 354 self.matcher = mp 355 356 self.selection_only = True
357 #------------------------------------------------------------------
358 - def _data2instance(self):
359 return gmVaccination.cVaccine(aPK_obj = self.GetData())
360 #---------------------------------------------------------------------- 361 from Gnumed.wxGladeWidgets import wxgVaccineEAPnl 362
363 -class cVaccineEAPnl(wxgVaccineEAPnl.wxgVaccineEAPnl, gmEditArea.cGenericEditAreaMixin):
364
365 - def __init__(self, *args, **kwargs):
366 367 try: 368 data = kwargs['vaccine'] 369 del kwargs['vaccine'] 370 except KeyError: 371 data = None 372 373 wxgVaccineEAPnl.wxgVaccineEAPnl.__init__(self, *args, **kwargs) 374 gmEditArea.cGenericEditAreaMixin.__init__(self) 375 376 self.mode = 'new' 377 self.data = data 378 if data is not None: 379 self.mode = 'edit' 380 381 self.__init_ui()
382 #----------------------------------------------------------------
383 - def __init_ui(self):
384 385 # # route 386 # query = u""" 387 # SELECT DISTINCT ON (abbreviation) 388 # id, 389 # abbreviation || ' (' || _(description) || ')' 390 # FROM 391 # clin.vacc_route 392 # WHERE 393 # abbreviation %(fragment_condition)s 394 # OR 395 # description %(fragment_condition)s 396 # ORDER BY 397 # abbreviation 398 # """ 399 # mp = gmMatchProvider.cMatchProvider_SQL2(queries=query) 400 # mp.setThresholds(1, 2, 3) 401 # self._PRW_route.matcher = mp 402 # self._PRW_route.selection_only = True 403 404 #self._PRW_age_min = gmPhraseWheel.cPhraseWheel(self, -1, "", style=wx.NO_BORDER) 405 #self._PRW_age_max = gmPhraseWheel.cPhraseWheel(self, -1, "", style=wx.NO_BORDER) 406 407 self.Layout() 408 self.Fit()
409 #---------------------------------------------------------------- 410 # generic Edit Area mixin API 411 #----------------------------------------------------------------
412 - def _valid_for_save(self):
413 414 has_errors = False 415 416 if self._PRW_brand.GetValue().strip() == u'': 417 has_errors = True 418 self._PRW_brand.display_as_valid(False) 419 else: 420 self._PRW_brand.display_as_valid(True) 421 422 # if self._PRW_route.GetData() is None: 423 # has_errors = True 424 # self._PRW_route.display_as_valid(False) 425 # else: 426 # self._PRW_route.display_as_valid(True) 427 428 if not self._PNL_indications.has_selection: 429 has_errors = True 430 431 if self._PRW_atc.GetValue().strip() in [u'', u'J07']: 432 self._PRW_atc.display_as_valid(True) 433 else: 434 if self._PRW_atc.GetData() is None: 435 self._PRW_atc.display_as_valid(True) 436 else: 437 has_errors = True 438 self._PRW_atc.display_as_valid(False) 439 440 val = self._PRW_age_min.GetValue().strip() 441 if val == u'': 442 self._PRW_age_min.display_as_valid(True) 443 else: 444 if gmDateTime.str2interval(val) is None: 445 has_errors = True 446 self._PRW_age_min.display_as_valid(False) 447 else: 448 self._PRW_age_min.display_as_valid(True) 449 450 val = self._PRW_age_max.GetValue().strip() 451 if val == u'': 452 self._PRW_age_max.display_as_valid(True) 453 else: 454 if gmDateTime.str2interval(val) is None: 455 has_errors = True 456 self._PRW_age_max.display_as_valid(False) 457 else: 458 self._PRW_age_max.display_as_valid(True) 459 460 # are we editing ? 461 ask_user = (self.mode == 'edit') 462 # is this vaccine in use ? 463 ask_user = (ask_user and self.data.is_in_use) 464 # a change ... 465 ask_user = ask_user and ( 466 # ... of brand ... 467 (self.data['pk_brand'] != self._PRW_route.GetData()) 468 or 469 # ... or indications ? 470 (self.data['indications'] != self._PNL_indications.selected_indications) 471 ) 472 473 if ask_user: 474 do_it = gmGuiHelpers.gm_show_question ( 475 aTitle = _('Saving vaccine'), 476 aMessage = _( 477 u'This vaccine is already in use:\n' 478 u'\n' 479 u' "%s"\n' 480 u' (%s)\n' 481 u'\n' 482 u'Are you absolutely positively sure that\n' 483 u'you really want to edit this vaccine ?\n' 484 '\n' 485 u'This will change the vaccine name and/or target\n' 486 u'conditions in each patient this vaccine was\n' 487 u'used in to document a vaccination with.\n' 488 ) % ( 489 self._PRW_brand.GetValue().strip(), 490 u', '.join(self.data['l10n_indications']) 491 ) 492 ) 493 if not do_it: 494 has_errors = True 495 496 return (has_errors is False)
497 #----------------------------------------------------------------
498 - def _save_as_new(self):
499 # save the data as a new instance 500 data = gmVaccination.create_vaccine ( 501 pk_brand = self._PRW_brand.GetData(), 502 brand_name = self._PRW_brand.GetValue(), 503 indications = self._PNL_indications.selected_indications 504 ) 505 506 # data['pk_route'] = self._PRW_route.GetData() 507 # data['is_live'] = self._CHBOX_live.GetValue() 508 val = self._PRW_age_min.GetValue().strip() 509 if val != u'': 510 data['min_age'] = gmDateTime.str2interval(val) 511 val = self._PRW_age_max.GetValue().strip() 512 if val != u'': 513 data['max_age'] = gmDateTime.str2interval(val) 514 val = self._TCTRL_comment.GetValue().strip() 515 if val != u'': 516 data['comment'] = val 517 518 data.save() 519 520 drug = data.brand 521 drug['is_fake_brand'] = self._CHBOX_fake.GetValue() 522 val = self._PRW_atc.GetData() 523 if val is not None: 524 if val != u'J07': 525 drug['atc'] = val.strip() 526 drug.save() 527 528 # must be done very late or else the property access 529 # will refresh the display such that later field 530 # access will return empty values 531 self.data = data 532 533 return True
534 #----------------------------------------------------------------
535 - def _save_as_update(self):
536 537 drug = self.data.brand 538 drug['brand'] = self._PRW_brand.GetValue().strip() 539 drug['is_fake_brand'] = self._CHBOX_fake.GetValue() 540 val = self._PRW_atc.GetData() 541 if val is not None: 542 if val != u'J07': 543 drug['atc'] = val.strip() 544 drug.save() 545 546 # the validator already asked for changes so just do it 547 self.data.set_indications(indications = self._PNL_indications.selected_indications) 548 549 # self.data['pk_route'] = self._PRW_route.GetData() 550 # self.data['is_live'] = self._CHBOX_live.GetValue() 551 val = self._PRW_age_min.GetValue().strip() 552 if val != u'': 553 self.data['min_age'] = gmDateTime.str2interval(val) 554 if val != u'': 555 self.data['max_age'] = gmDateTime.str2interval(val) 556 val = self._TCTRL_comment.GetValue().strip() 557 if val != u'': 558 self.data['comment'] = val 559 560 self.data.save() 561 return True
562 #----------------------------------------------------------------
563 - def _refresh_as_new(self):
564 self._PRW_brand.SetText(value = u'', data = None, suppress_smarts = True) 565 # self._PRW_route.SetText(value = u'intramuscular') 566 # self._CHBOX_live.SetValue(True) 567 self._CHBOX_fake.SetValue(False) 568 self._PNL_indications.clear_all() 569 self._PRW_atc.SetText(value = u'', data = None, suppress_smarts = True) 570 self._PRW_age_min.SetText(value = u'', data = None, suppress_smarts = True) 571 self._PRW_age_max.SetText(value = u'', data = None, suppress_smarts = True) 572 self._TCTRL_comment.SetValue(u'') 573 574 self._PRW_brand.SetFocus()
575 #----------------------------------------------------------------
576 - def _refresh_from_existing(self):
577 self._PRW_brand.SetText(value = self.data['vaccine'], data = self.data['pk_brand']) 578 # self._PRW_route.SetText(value = self.data['route_description'], data = self.data['pk_route']) 579 # self._CHBOX_live.SetValue(self.data['is_live']) 580 self._CHBOX_fake.SetValue(self.data['is_fake_vaccine']) 581 self._PNL_indications.select(self.data['indications']) 582 self._PRW_atc.SetText(value = self.data['atc_code'], data = self.data['atc_code']) 583 if self.data['min_age'] is None: 584 self._PRW_age_min.SetText(value = u'', data = None, suppress_smarts = True) 585 else: 586 self._PRW_age_min.SetText ( 587 value = gmDateTime.format_interval(self.data['min_age'], gmDateTime.acc_years), 588 data = self.data['min_age'] 589 ) 590 if self.data['max_age'] is None: 591 self._PRW_age_max.SetText(value = u'', data = None, suppress_smarts = True) 592 else: 593 self._PRW_age_max.SetText ( 594 value = gmDateTime.format_interval(self.data['max_age'], gmDateTime.acc_years), 595 data = self.data['max_age'] 596 ) 597 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u'')) 598 599 self._PRW_brand.SetFocus()
600 #----------------------------------------------------------------
602 self._refresh_as_new()
603 #====================================================================== 604 # vaccination related widgets 605 #----------------------------------------------------------------------
606 -def edit_vaccination(parent=None, vaccination=None, single_entry=True):
607 ea = cVaccinationEAPnl(parent = parent, id = -1) 608 ea.data = vaccination 609 ea.mode = gmTools.coalesce(vaccination, 'new', 'edit') 610 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 611 dlg.SetTitle(gmTools.coalesce(vaccination, _('Adding new vaccinations'), _('Editing vaccination'))) 612 if dlg.ShowModal() == wx.ID_OK: 613 dlg.Destroy() 614 return True 615 dlg.Destroy() 616 if not single_entry: 617 return True 618 return False
619 #----------------------------------------------------------------------
620 -def manage_vaccinations(parent=None):
621 622 pat = gmPerson.gmCurrentPatient() 623 emr = pat.get_emr() 624 625 if parent is None: 626 parent = wx.GetApp().GetTopWindow() 627 #------------------------------------------------------------ 628 def browse2schedules(vaccination=None): 629 dbcfg = gmCfg.cCfgSQL() 630 url = dbcfg.get2 ( 631 option = 'external.urls.vaccination_plans', 632 workplace = gmSurgery.gmCurrentPractice().active_workplace, 633 bias = 'user', 634 default = u'http://www.bundesaerztekammer.de/downloads/ImpfempfehlungenRKI2009.pdf' 635 ) 636 637 gmNetworkTools.open_url_in_browser(url = url) 638 return False
639 #------------------------------------------------------------ 640 def edit(vaccination=None): 641 return edit_vaccination(parent = parent, vaccination = vaccination, single_entry = (vaccination is not None)) 642 #------------------------------------------------------------ 643 def delete(vaccination=None): 644 gmVaccination.delete_vaccination(vaccination = vaccination['pk_vaccination']) 645 return True 646 #------------------------------------------------------------ 647 def refresh(lctrl): 648 649 vaccs = emr.get_vaccinations(order_by = 'date_given DESC, pk_vaccination') 650 651 items = [ [ 652 v['date_given'].strftime('%Y %B %d').decode(gmI18N.get_encoding()), 653 v['vaccine'], 654 u', '.join(v['l10n_indications']), 655 v['batch_no'], 656 gmTools.coalesce(v['site'], u''), 657 gmTools.coalesce(v['reaction'], u''), 658 gmTools.coalesce(v['comment'], u'') 659 ] for v in vaccs ] 660 661 lctrl.set_string_items(items) 662 lctrl.set_data(vaccs) 663 #------------------------------------------------------------ 664 gmListWidgets.get_choices_from_list ( 665 parent = parent, 666 msg = _('\nComplete vaccination history for this patient.\n'), 667 caption = _('Showing vaccinations.'), 668 columns = [ _('Date'), _('Vaccine'), _(u'Intended to protect from'), _('Batch'), _('Site'), _('Reaction'), _('Comment') ], 669 single_selection = True, 670 refresh_callback = refresh, 671 new_callback = edit, 672 edit_callback = edit, 673 delete_callback = delete, 674 left_extra_button = (_('Vaccination Plans'), _('Open a browser showing vaccination schedules.'), browse2schedules) 675 ) 676 #---------------------------------------------------------------------- 677 from Gnumed.wxGladeWidgets import wxgVaccinationEAPnl 678
679 -class cVaccinationEAPnl(wxgVaccinationEAPnl.wxgVaccinationEAPnl, gmEditArea.cGenericEditAreaMixin):
680 """ 681 - warn on apparent duplicates 682 - ask if "missing" (= previous, non-recorded) vaccinations 683 should be estimated and saved (add note "auto-generated") 684 685 Batch No (http://www.fao.org/docrep/003/v9952E12.htm) 686 """
687 - def __init__(self, *args, **kwargs):
688 689 try: 690 data = kwargs['vaccination'] 691 del kwargs['vaccination'] 692 except KeyError: 693 data = None 694 695 wxgVaccinationEAPnl.wxgVaccinationEAPnl.__init__(self, *args, **kwargs) 696 gmEditArea.cGenericEditAreaMixin.__init__(self) 697 698 self.mode = 'new' 699 self.data = data 700 if data is not None: 701 self.mode = 'edit' 702 703 self.__init_ui()
704 #----------------------------------------------------------------
705 - def __init_ui(self):
706 # adjust phrasewheels etc 707 self._PRW_vaccine.add_callback_on_lose_focus(self._on_PRW_vaccine_lost_focus) 708 self._PRW_provider.selection_only = False 709 # self._PRW_batch.unset_context(context = 'pk_vaccine') # done in PRW init() 710 self._PRW_reaction.add_callback_on_lose_focus(self._on_PRW_reaction_lost_focus)
711 #----------------------------------------------------------------
712 - def _on_PRW_vaccine_lost_focus(self):
713 714 vaccine = self._PRW_vaccine.GetData(as_instance=True) 715 716 # if we are editing we do not allow using indications rather than a vaccine 717 if self.mode == u'edit': 718 self._PNL_indications.clear_all() 719 if vaccine is None: 720 self._PRW_batch.unset_context(context = 'pk_vaccine') 721 else: 722 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine']) 723 self._PNL_indications.select(indications = vaccine['indications']) 724 self._PNL_indications.disable_all() 725 726 # we are entering a new vaccination 727 else: 728 if vaccine is None: 729 self._PRW_batch.unset_context(context = 'pk_vaccine') 730 self._PNL_indications.enable_all() 731 else: 732 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine']) 733 self._PNL_indications.clear_all() 734 self._PNL_indications.select(indications = vaccine['indications']) 735 self._PNL_indications.disable_all()
736 #----------------------------------------------------------------
738 if self._PRW_reaction.GetValue().strip() == u'': 739 self._BTN_report.Enable(False) 740 else: 741 self._BTN_report.Enable(True)
742 #---------------------------------------------------------------- 743 # generic Edit Area mixin API 744 #----------------------------------------------------------------
745 - def _valid_for_save(self):
746 747 has_errors = False 748 749 if not self._PRW_date_given.is_valid_timestamp(allow_empty = False): 750 has_errors = True 751 752 vaccine = self._PRW_vaccine.GetData(as_instance = True) 753 754 # we are editing, require vaccine rather than indications 755 if self.mode == u'edit': 756 if vaccine is None: 757 has_errors = True 758 self._PRW_vaccine.display_as_valid(False) 759 else: 760 self._PRW_vaccine.display_as_valid(True) 761 self._PNL_indications.clear_all() 762 self._PNL_indications.select(indications = vaccine['indications']) 763 self._PNL_indications.disable_all() 764 # we are creating, allow either vaccine or indications 765 else: 766 if vaccine is None: 767 if self._PNL_indications.has_selection: 768 self._PRW_vaccine.display_as_valid(True) 769 else: 770 has_errors = True 771 self._PRW_vaccine.display_as_valid(False) 772 else: 773 self._PRW_vaccine.display_as_valid(True) 774 775 if self._PRW_batch.GetValue().strip() == u'': 776 has_errors = True 777 self._PRW_batch.display_as_valid(False) 778 else: 779 self._PRW_batch.display_as_valid(True) 780 781 if self._PRW_episode.GetValue().strip() == u'': 782 self._PRW_episode.SetText(value = _('prevention')) 783 784 return (has_errors is False)
785 #----------------------------------------------------------------
786 - def _save_as_new(self):
787 788 vaccine = self._PRW_vaccine.GetData() 789 if vaccine is None: 790 data = self.__save_new_from_indications() 791 else: 792 data = self.__save_new_from_vaccine(vaccine = vaccine) 793 794 # must be done very late or else the property access 795 # will refresh the display such that later field 796 # access will return empty values 797 self.data = data 798 799 return True
800 #----------------------------------------------------------------
802 803 inds = self._PNL_indications.selected_indications 804 vaccine = gmVaccination.map_indications2generic_vaccine(indications = inds) 805 806 if vaccine is None: 807 for ind in inds: 808 vaccine = gmVaccination.map_indications2generic_vaccine(indications = [ind]) 809 data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine']) 810 else: 811 data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine']) 812 813 return data
814 #----------------------------------------------------------------
815 - def __save_new_from_vaccine(self, vaccine=None):
816 817 emr = gmPerson.gmCurrentPatient().get_emr() 818 819 data = emr.add_vaccination ( 820 episode = self._PRW_episode.GetData(can_create = True, is_open = False), 821 vaccine = vaccine, 822 batch_no = self._PRW_batch.GetValue().strip() 823 ) 824 825 if self._CHBOX_anamnestic.GetValue() is True: 826 data['soap_cat'] = u's' 827 else: 828 data['soap_cat'] = u'p' 829 830 data['date_given'] = self._PRW_date_given.GetData() 831 data['site'] = self._PRW_site.GetValue().strip() 832 data['pk_provider'] = self._PRW_provider.GetData() 833 data['reaction'] = self._PRW_reaction.GetValue().strip() 834 data['comment'] = self._TCTRL_comment.GetValue().strip() 835 836 data.save() 837 838 return data
839 #----------------------------------------------------------------
840 - def _save_as_update(self):
841 842 if self._CHBOX_anamnestic.GetValue() is True: 843 self.data['soap_cat'] = u's' 844 else: 845 self.data['soap_cat'] = u'p' 846 847 self.data['date_given'] = self._PRW_date_given.GetData() 848 self.data['pk_vaccine'] = self._PRW_vaccine.GetData() 849 self.data['batch_no'] = self._PRW_batch.GetValue().strip() 850 self.data['pk_episode'] = self._PRW_episode.GetData(can_create = True, is_open = False) 851 self.data['site'] = self._PRW_site.GetValue().strip() 852 self.data['pk_provider'] = self._PRW_provider.GetData() 853 self.data['reaction'] = self._PRW_reaction.GetValue().strip() 854 self.data['comment'] = self._TCTRL_comment.GetValue().strip() 855 856 self.data.save() 857 858 return True
859 #----------------------------------------------------------------
860 - def _refresh_as_new(self):
861 self._PRW_date_given.SetText(data = gmDateTime.pydt_now_here()) 862 self._CHBOX_anamnestic.SetValue(False) 863 self._PRW_vaccine.SetText(value = u'', data = None, suppress_smarts = True) 864 865 self._PNL_indications.clear_all() 866 self._PRW_batch.unset_context(context = 'pk_vaccine') 867 self._PRW_batch.SetValue(u'') 868 869 self._PRW_episode.SetText(value = u'', data = None, suppress_smarts = True) 870 self._PRW_site.SetValue(u'') 871 self._PRW_provider.SetData(data = None) 872 self._PRW_reaction.SetText(value = u'', data = None, suppress_smarts = True) 873 self._BTN_report.Enable(False) 874 self._TCTRL_comment.SetValue(u'') 875 876 self._PRW_date_given.SetFocus()
877 #----------------------------------------------------------------
878 - def _refresh_from_existing(self):
879 self._PRW_date_given.SetText(data = self.data['date_given']) 880 if self.data['soap_cat'] == u's': 881 self._CHBOX_anamnestic.SetValue(True) 882 else: 883 self._CHBOX_anamnestic.SetValue(False) 884 self._PRW_vaccine.SetText(value = self.data['vaccine'], data = self.data['pk_vaccine']) 885 886 self._PNL_indications.clear_all() 887 self._PNL_indications.select(indications = self.data['indications']) 888 self._PNL_indications.disable_all() 889 890 self._PRW_batch.SetValue(self.data['batch_no']) 891 self._PRW_episode.SetData(data = self.data['pk_episode']) 892 self._PRW_site.SetValue(gmTools.coalesce(self.data['site'], u'')) 893 self._PRW_provider.SetData(self.data['pk_provider']) 894 self._PRW_reaction.SetValue(gmTools.coalesce(self.data['reaction'], u'')) 895 if self.data['reaction'] is None: 896 self._BTN_report.Enable(False) 897 else: 898 self._BTN_report.Enable(True) 899 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u'')) 900 901 self._PRW_date_given.SetFocus()
902 #----------------------------------------------------------------
904 self._PRW_date_given.SetText(data = self.data['date_given']) 905 #self._CHBOX_anamnestic.SetValue(False) 906 self._PRW_vaccine.SetText(value = self.data['vaccine'], data = self.data['pk_vaccine']) 907 908 self._PNL_indications.clear_all() 909 self._PNL_indications.select(indications = self.data['indications']) 910 self._PNL_indications.disable_all() 911 912 self._PRW_batch.set_context(context = 'pk_vaccine', val = self.data['pk_vaccine']) 913 self._PRW_batch.SetValue(u'') 914 915 self._PRW_episode.SetData(data = self.data['pk_episode']) 916 self._PRW_site.SetValue(gmTools.coalesce(self.data['site'], u'')) 917 self._PRW_provider.SetData(self.data['pk_provider']) 918 self._PRW_reaction.SetValue(u'') 919 self._BTN_report.Enable(False) 920 self._TCTRL_comment.SetValue(u'') 921 922 self._PRW_date_given.SetFocus()
923 #---------------------------------------------------------------- 924 # event handlers 925 #----------------------------------------------------------------
926 - def _on_report_button_pressed(self, event):
927 928 event.Skip() 929 930 dbcfg = gmCfg.cCfgSQL() 931 932 url = dbcfg.get2 ( 933 option = u'external.urls.report_vaccine_ADR', 934 workplace = gmSurgery.gmCurrentPractice().active_workplace, 935 bias = u'user', 936 default = u'http://www.pei.de/cln_042/SharedDocs/Downloads/fachkreise/uaw/meldeboegen/b-ifsg-meldebogen,templateId=raw,property=publicationFile.pdf/b-ifsg-meldebogen.pdf' 937 ) 938 939 if url.strip() == u'': 940 url = dbcfg.get2 ( 941 option = u'external.urls.report_ADR', 942 workplace = gmSurgery.gmCurrentPractice().active_workplace, 943 bias = u'user' 944 ) 945 gmNetworkTools.open_url_in_browser(url = url)
946 #----------------------------------------------------------------
947 - def _on_add_vaccine_button_pressed(self, event):
948 edit_vaccine(parent = self, vaccine = None, single_entry = False)
949 # FIXME: could set newly generated vaccine here 950 #====================================================================== 951 #======================================================================
952 -class cImmunisationsPanel(wx.Panel, gmRegetMixin.cRegetOnPaintMixin):
953
954 - def __init__(self, parent, id):
955 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER) 956 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 957 self.__pat = gmPerson.gmCurrentPatient() 958 # do this here so "import cImmunisationsPanel from gmVaccWidgets" works 959 self.ID_VaccinatedIndicationsList = wx.NewId() 960 self.ID_VaccinationsPerRegimeList = wx.NewId() 961 self.ID_MissingShots = wx.NewId() 962 self.ID_ActiveSchedules = wx.NewId() 963 self.__do_layout() 964 self.__register_interests() 965 self.__reset_ui_content()
966 #----------------------------------------------------
967 - def __do_layout(self):
968 #----------------------------------------------- 969 # top part 970 #----------------------------------------------- 971 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _(" IMMUNISATIONS ")) 972 self.editarea = cVaccinationEditArea(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER) 973 974 #----------------------------------------------- 975 # middle part 976 #----------------------------------------------- 977 # divider headings below editing area 978 indications_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Indications")) 979 vaccinations_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Vaccinations")) 980 schedules_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Active Schedules")) 981 szr_MiddleCap = wx.BoxSizer(wx.HORIZONTAL) 982 szr_MiddleCap.Add(indications_heading, 4, wx.EXPAND) 983 szr_MiddleCap.Add(vaccinations_heading, 6, wx.EXPAND) 984 szr_MiddleCap.Add(schedules_heading, 10, wx.EXPAND) 985 986 # left list: indications for which vaccinations have been given 987 self.LBOX_vaccinated_indications = wx.ListBox( 988 parent = self, 989 id = self.ID_VaccinatedIndicationsList, 990 choices = [], 991 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 992 ) 993 self.LBOX_vaccinated_indications.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 994 995 # right list: when an indication has been selected on the left 996 # display the corresponding vaccinations on the right 997 self.LBOX_given_shots = wx.ListBox( 998 parent = self, 999 id = self.ID_VaccinationsPerRegimeList, 1000 choices = [], 1001 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1002 ) 1003 self.LBOX_given_shots.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1004 1005 self.LBOX_active_schedules = wx.ListBox ( 1006 parent = self, 1007 id = self.ID_ActiveSchedules, 1008 choices = [], 1009 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1010 ) 1011 self.LBOX_active_schedules.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1012 1013 szr_MiddleLists = wx.BoxSizer(wx.HORIZONTAL) 1014 szr_MiddleLists.Add(self.LBOX_vaccinated_indications, 4, wx.EXPAND) 1015 szr_MiddleLists.Add(self.LBOX_given_shots, 6, wx.EXPAND) 1016 szr_MiddleLists.Add(self.LBOX_active_schedules, 10, wx.EXPAND) 1017 1018 #--------------------------------------------- 1019 # bottom part 1020 #--------------------------------------------- 1021 missing_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Missing Immunisations")) 1022 szr_BottomCap = wx.BoxSizer(wx.HORIZONTAL) 1023 szr_BottomCap.Add(missing_heading, 1, wx.EXPAND) 1024 1025 self.LBOX_missing_shots = wx.ListBox ( 1026 parent = self, 1027 id = self.ID_MissingShots, 1028 choices = [], 1029 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1030 ) 1031 self.LBOX_missing_shots.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1032 1033 szr_BottomLists = wx.BoxSizer(wx.HORIZONTAL) 1034 szr_BottomLists.Add(self.LBOX_missing_shots, 1, wx.EXPAND) 1035 1036 # alert caption 1037 pnl_AlertCaption = gmTerryGuiParts.cAlertCaption(self, -1, _(' Alerts ')) 1038 1039 #--------------------------------------------- 1040 # add all elements to the main background sizer 1041 #--------------------------------------------- 1042 self.mainsizer = wx.BoxSizer(wx.VERTICAL) 1043 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND) 1044 self.mainsizer.Add(self.editarea, 6, wx.EXPAND) 1045 self.mainsizer.Add(szr_MiddleCap, 0, wx.EXPAND) 1046 self.mainsizer.Add(szr_MiddleLists, 4, wx.EXPAND) 1047 self.mainsizer.Add(szr_BottomCap, 0, wx.EXPAND) 1048 self.mainsizer.Add(szr_BottomLists, 4, wx.EXPAND) 1049 self.mainsizer.Add(pnl_AlertCaption, 0, wx.EXPAND) 1050 1051 self.SetAutoLayout(True) 1052 self.SetSizer(self.mainsizer) 1053 self.mainsizer.Fit(self)
1054 #----------------------------------------------------
1055 - def __register_interests(self):
1056 # wxPython events 1057 wx.EVT_SIZE(self, self.OnSize) 1058 wx.EVT_LISTBOX(self, self.ID_VaccinatedIndicationsList, self._on_vaccinated_indication_selected) 1059 wx.EVT_LISTBOX_DCLICK(self, self.ID_VaccinationsPerRegimeList, self._on_given_shot_selected) 1060 wx.EVT_LISTBOX_DCLICK(self, self.ID_MissingShots, self._on_missing_shot_selected) 1061 # wx.EVT_RIGHT_UP(self.lb1, self.EvtRightButton) 1062 1063 # client internal signals 1064 gmDispatcher.connect(signal= u'post_patient_selection', receiver=self._schedule_data_reget) 1065 gmDispatcher.connect(signal= u'vaccinations_updated', receiver=self._schedule_data_reget)
1066 #---------------------------------------------------- 1067 # event handlers 1068 #----------------------------------------------------
1069 - def OnSize (self, event):
1070 w, h = event.GetSize() 1071 self.mainsizer.SetDimension (0, 0, w, h)
1072 #----------------------------------------------------
1073 - def _on_given_shot_selected(self, event):
1074 """Paste previously given shot into edit area. 1075 """ 1076 self.editarea.set_data(aVacc=event.GetClientData())
1077 #----------------------------------------------------
1078 - def _on_missing_shot_selected(self, event):
1079 self.editarea.set_data(aVacc = event.GetClientData())
1080 #----------------------------------------------------
1081 - def _on_vaccinated_indication_selected(self, event):
1082 """Update right hand middle list to show vaccinations given for selected indication.""" 1083 ind_list = event.GetEventObject() 1084 selected_item = ind_list.GetSelection() 1085 ind = ind_list.GetClientData(selected_item) 1086 # clear list 1087 self.LBOX_given_shots.Set([]) 1088 emr = self.__pat.get_emr() 1089 shots = emr.get_vaccinations(indications = [ind]) 1090 # FIXME: use Set() for entire array (but problem with client_data) 1091 for shot in shots: 1092 if shot['is_booster']: 1093 marker = 'B' 1094 else: 1095 marker = '#%s' % shot['seq_no'] 1096 label = '%s - %s: %s' % (marker, shot['date'].strftime('%m/%Y'), shot['vaccine']) 1097 self.LBOX_given_shots.Append(label, shot)
1098 #----------------------------------------------------
1099 - def __reset_ui_content(self):
1100 # clear edit area 1101 self.editarea.set_data() 1102 # clear lists 1103 self.LBOX_vaccinated_indications.Clear() 1104 self.LBOX_given_shots.Clear() 1105 self.LBOX_active_schedules.Clear() 1106 self.LBOX_missing_shots.Clear()
1107 #----------------------------------------------------
1108 - def _populate_with_data(self):
1109 # clear lists 1110 self.LBOX_vaccinated_indications.Clear() 1111 self.LBOX_given_shots.Clear() 1112 self.LBOX_active_schedules.Clear() 1113 self.LBOX_missing_shots.Clear() 1114 1115 emr = self.__pat.get_emr() 1116 1117 t1 = time.time() 1118 # populate vaccinated-indications list 1119 # FIXME: consider adding virtual indication "most recent" to 1120 # FIXME: display most recent of all indications as suggested by Syan 1121 status, indications = emr.get_vaccinated_indications() 1122 # FIXME: would be faster to use Set() but can't 1123 # use Set(labels, client_data), and have to know 1124 # line position in SetClientData :-( 1125 for indication in indications: 1126 self.LBOX_vaccinated_indications.Append(indication[1], indication[0]) 1127 # self.LBOX_vaccinated_indications.Set(lines) 1128 # self.LBOX_vaccinated_indications.SetClientData(data) 1129 print "vaccinated indications took", time.time()-t1, "seconds" 1130 1131 t1 = time.time() 1132 # populate active schedules list 1133 scheds = emr.get_scheduled_vaccination_regimes() 1134 if scheds is None: 1135 label = _('ERROR: cannot retrieve active vaccination schedules') 1136 self.LBOX_active_schedules.Append(label) 1137 elif len(scheds) == 0: 1138 label = _('no active vaccination schedules') 1139 self.LBOX_active_schedules.Append(label) 1140 else: 1141 for sched in scheds: 1142 label = _('%s for %s (%s shots): %s') % (sched['regime'], sched['l10n_indication'], sched['shots'], sched['comment']) 1143 self.LBOX_active_schedules.Append(label) 1144 print "active schedules took", time.time()-t1, "seconds" 1145 1146 t1 = time.time() 1147 # populate missing-shots list 1148 missing_shots = emr.get_missing_vaccinations() 1149 print "getting missing shots took", time.time()-t1, "seconds" 1150 if missing_shots is None: 1151 label = _('ERROR: cannot retrieve due/overdue vaccinations') 1152 self.LBOX_missing_shots.Append(label, None) 1153 return True 1154 # due 1155 due_template = _('%.0d weeks left: shot %s for %s in %s, due %s (%s)') 1156 overdue_template = _('overdue %.0dyrs %.0dwks: shot %s for %s in schedule "%s" (%s)') 1157 for shot in missing_shots['due']: 1158 if shot['overdue']: 1159 years, days_left = divmod(shot['amount_overdue'].days, 364.25) 1160 weeks = days_left / 7 1161 # amount_overdue, seq_no, indication, regime, vacc_comment 1162 label = overdue_template % ( 1163 years, 1164 weeks, 1165 shot['seq_no'], 1166 shot['l10n_indication'], 1167 shot['regime'], 1168 shot['vacc_comment'] 1169 ) 1170 self.LBOX_missing_shots.Append(label, shot) 1171 else: 1172 # time_left, seq_no, regime, latest_due, vacc_comment 1173 label = due_template % ( 1174 shot['time_left'].days / 7, 1175 shot['seq_no'], 1176 shot['indication'], 1177 shot['regime'], 1178 shot['latest_due'].strftime('%m/%Y'), 1179 shot['vacc_comment'] 1180 ) 1181 self.LBOX_missing_shots.Append(label, shot) 1182 # booster 1183 lbl_template = _('due now: booster for %s in schedule "%s" (%s)') 1184 for shot in missing_shots['boosters']: 1185 # indication, regime, vacc_comment 1186 label = lbl_template % ( 1187 shot['l10n_indication'], 1188 shot['regime'], 1189 shot['vacc_comment'] 1190 ) 1191 self.LBOX_missing_shots.Append(label, shot) 1192 print "displaying missing shots took", time.time()-t1, "seconds" 1193 1194 return True
1195 #----------------------------------------------------
1196 - def _on_post_patient_selection(self, **kwargs):
1197 return 1
1198 # FIXME: 1199 # if has_focus: 1200 # wxCallAfter(self.__reset_ui_content) 1201 # else: 1202 # return 1 1203 #----------------------------------------------------
1204 - def _on_vaccinations_updated(self, **kwargs):
1205 return 1
1206 # FIXME: 1207 # if has_focus: 1208 # wxCallAfter(self.__reset_ui_content) 1209 # else: 1210 # is_stale == True 1211 # return 1 1212 #====================================================================== 1213 # main 1214 #---------------------------------------------------------------------- 1215 if __name__ == "__main__": 1216 1217 if len(sys.argv) < 2: 1218 sys.exit() 1219 1220 if sys.argv[1] != u'test': 1221 sys.exit() 1222 1223 app = wx.PyWidgetTester(size = (600, 600)) 1224 app.SetWidget(cATCPhraseWheel, -1) 1225 app.MainLoop() 1226 #====================================================================== 1227