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