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 (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
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
32
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
69
70 -def edit_vaccine(parent=None, vaccine=None, single_entry=True):
81
83
84 if parent is None:
85 parent = wx.GetApp().GetTopWindow()
86
87 def delete(vaccine=None):
88 deleted = gmVaccination.delete_vaccine(vaccine = vaccine['pk_vaccine'])
89 if deleted:
90 return True
91
92 gmGuiHelpers.gm_show_info (
93 _(
94 'Cannot delete vaccine\n'
95 '\n'
96 ' %s - %s (#%s)\n'
97 '\n'
98 'It is probably documented in a vaccination.'
99 ) % (
100 vaccine['vaccine'],
101 vaccine['preparation'],
102 vaccine['pk_vaccine']
103 ),
104 _('Deleting vaccine')
105 )
106
107 return False
108
109 def edit(vaccine=None):
110 return edit_vaccine(parent = parent, vaccine = vaccine, single_entry = True)
111
112 def refresh(lctrl):
113 vaccines = gmVaccination.get_vaccines(order_by = 'vaccine')
114
115 items = [ [
116 u'%s' % v['pk_brand'],
117 u'%s%s' % (
118 v['vaccine'],
119 gmTools.bool2subst (
120 v['is_fake_vaccine'],
121 u' (%s)' % _('fake'),
122 u''
123 )
124 ),
125 v['preparation'],
126 u'%s (%s)' % (v['route_abbreviation'], v['route_description']),
127 gmTools.bool2subst(v['is_live'], gmTools.u_checkmark_thin, u''),
128 gmTools.coalesce(v['atc_code'], u''),
129 u'%s%s' % (
130 gmTools.coalesce(v['min_age'], u'?'),
131 gmTools.coalesce(v['max_age'], u'?', u' - %s'),
132 ),
133 gmTools.coalesce(v['comment'], u'')
134 ] for v in vaccines ]
135 lctrl.set_string_items(items)
136 lctrl.set_data(vaccines)
137
138 gmListWidgets.get_choices_from_list (
139 parent = parent,
140 msg = _('\nThe vaccines currently known to GNUmed.\n'),
141 caption = _('Showing vaccines.'),
142 columns = [ u'#', _('Brand'), _('Preparation'), _(u'Route'), _('Live'), _('ATC'), _('Age range'), _('Comment') ],
143 single_selection = True,
144 refresh_callback = refresh,
145 edit_callback = edit,
146 new_callback = edit,
147 delete_callback = delete
148 )
149
151
153
154 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
155
156 context = {
157 u'ctxt_vaccine': {
158 u'where_part': u'AND pk_vaccine = %(pk_vaccine)s',
159 u'placeholder': u'pk_vaccine'
160 }
161 }
162
163 query = u"""
164 SELECT code, batch_no FROM (
165
166 SELECT distinct on (batch_no) code, batch_no, rank FROM (
167
168 (
169 -- batch_no by vaccine
170 SELECT
171 batch_no AS code,
172 batch_no,
173 1 AS rank
174 FROM
175 clin.v_pat_vaccinations
176 WHERE
177 batch_no %(fragment_condition)s
178 %(ctxt_vaccine)s
179 ) UNION ALL (
180 -- batch_no for any vaccine
181 SELECT
182 batch_no AS code,
183 batch_no,
184 2 AS rank
185 FROM
186 clin.v_pat_vaccinations
187 WHERE
188 batch_no %(fragment_condition)s
189 )
190
191 ) AS matching_batch_nos
192
193 ) as unique_matches
194
195 ORDER BY rank, batch_no
196 LIMIT 25
197 """
198 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query, context = context)
199 mp.setThresholds(1, 2, 3)
200 self.matcher = mp
201
202 self.unset_context(context = u'pk_vaccine')
203 self.SetToolTipString(_('Enter or select the batch/lot number of the vaccine used.'))
204 self.selection_only = False
205
207
209
210 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
211
212
213 query = u"""
214 SELECT pk_vaccine, description FROM (
215
216 SELECT DISTINCT ON (pk_vaccine) pk_vaccine, description FROM (
217
218 (
219 -- fragment -> vaccine
220 SELECT
221 pk_vaccine,
222 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')'
223 AS description
224 FROM
225 clin.v_vaccines
226 WHERE
227 vaccine %(fragment_condition)s
228
229 ) union all (
230
231 -- fragment -> localized indication -> vaccines
232 SELECT
233 pk_vaccine,
234 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')'
235 AS description
236 FROM
237 clin.v_indications4vaccine
238 WHERE
239 l10n_indication %(fragment_condition)s
240
241 ) union all (
242
243 -- fragment -> indication -> vaccines
244 SELECT
245 pk_vaccine,
246 vaccine || ' (' || array_to_string(indications, ', ') || ')'
247 AS description
248 FROM
249 clin.v_indications4vaccine
250 WHERE
251 indication %(fragment_condition)s
252 )
253 ) AS distinct_total
254
255 ) AS total
256
257 ORDER by description
258 LIMIT 25
259 """
260 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query)
261 mp.setThresholds(1, 2, 3)
262 self.matcher = mp
263
264 self.selection_only = True
265
268
269 from Gnumed.wxGladeWidgets import wxgVaccineEAPnl
270
271 -class cVaccineEAPnl(wxgVaccineEAPnl.wxgVaccineEAPnl, gmEditArea.cGenericEditAreaMixin):
272
290
292
293 self._PRW_route.selection_only = True
294
295 self.Layout()
296 self.Fit()
297
298
299
349
351
352 data = 1
353
354 data[''] = 1
355 data[''] = 1
356
357
358
359
360
361
362
363 return False
364 return True
365
367
368 self.data[''] = 1
369 self.data[''] = 1
370 self.data[''] = 1
371
372 return True
373
384
386 self._PRW_brand.SetText(value = self.data['vaccine'], data = self.data['pk_brand'])
387 self._PRW_route.SetText(value = self.data['route_description'], data = self.data['pk_route'])
388 self._CHBOX_live.SetValue(self.data['is_live'])
389 self._CHBOX_fake.SetValue(self.data['is_fake_vaccine'])
390 self._PNL_indications.select(self.data['indications'])
391 self._PRW_atc.SetText(value = self.data['atc_code'], data = self.data['atc_code'])
392 if self.data['min_age'] is None:
393 self._PRW_age_min.SetText(value = u'', data = None, suppress_smarts = True)
394 else:
395 self._PRW_age_min.SetText (
396 value = gmDateTime.format_interval(self.data['min_age'], gmDateTime.acc_years),
397 data = self.data['min_age']
398 )
399 if self.data['max_age'] is None:
400 self._PRW_age_max.SetText(value = u'', data = None, suppress_smarts = True)
401 else:
402 self._PRW_age_max.SetText (
403 value = gmDateTime.format_interval(self.data['max_age'], gmDateTime.acc_years),
404 data = self.data['max_age']
405 )
406 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u''))
407
409 self._refresh_as_new()
410
411
412
424
426
427 pat = gmPerson.gmCurrentPatient()
428 emr = pat.get_emr()
429
430 if parent is None:
431 parent = wx.GetApp().GetTopWindow()
432
433
434 def edit(vaccination=None):
435 return edit_vaccination(parent = parent, vaccination = vaccination, single_entry = True)
436
437 def delete(vaccination=None):
438 gmVaccination.delete_vaccination(vaccination = vaccination['pk_vaccination'])
439 return True
440
441 def refresh(lctrl):
442
443 vaccs = emr.get_vaccinations(order_by = 'date_given DESC, pk_vaccination')
444
445 items = [ [
446 v['date_given'].strftime('%Y %B %d').decode(gmI18N.get_encoding()),
447 v['vaccine'],
448 u', '.join(v['l10n_indications']),
449 v['batch_no'],
450 gmTools.coalesce(v['site'], u''),
451 gmTools.coalesce(v['reaction'], u''),
452 gmTools.coalesce(v['comment'], u'')
453 ] for v in vaccs ]
454
455 lctrl.set_string_items(items)
456 lctrl.set_data(vaccs)
457
458 gmListWidgets.get_choices_from_list (
459 parent = parent,
460 msg = _('\nComplete vaccination history for this patient.\n'),
461 caption = _('Showing vaccinations.'),
462 columns = [ _('Date'), _('Vaccine'), _(u'Intended to protect from'), _('Batch'), _('Site'), _('Reaction'), _('Comment') ],
463 single_selection = True,
464 refresh_callback = refresh,
465 new_callback = edit,
466 edit_callback = edit,
467 delete_callback = delete
468 )
469
470 from Gnumed.wxGladeWidgets import wxgVaccinationIndicationsPnl
471
473
475
476 wxgVaccinationIndicationsPnl.wxgVaccinationIndicationsPnl.__init__(self, *args, **kwargs)
477
478 self.__indication2field = {
479 u'coxiella burnetii (Q fever)': self._CHBOX_coxq,
480 u'salmonella typhi (typhoid)': self._CHBOX_typhoid,
481 u'varicella (chickenpox, shingles)': self._CHBOX_varicella,
482 u'influenza (seasonal)': self._CHBOX_influenza,
483 u'bacillus anthracis (Anthrax)': self._CHBOX_anthrax,
484 u'human papillomavirus': self._CHBOX_hpv,
485 u'rotavirus': self._CHBOX_rota,
486 u'tuberculosis': self._CHBOX_tuberculosis,
487 u'variola virus (smallpox)': self._CHBOX_smallpox,
488 u'influenza (H1N1)': self._CHBOX_h1n1,
489 u'cholera': self._CHBOX_cholera,
490 u'diphtheria': self._CHBOX_diphtheria,
491 u'haemophilus influenzae b': self._CHBOX_hib,
492 u'hepatitis A': self._CHBOX_hepA,
493 u'hepatitis B': self._CHBOX_hepB,
494 u'japanese B encephalitis': self._CHBOX_japanese,
495 u'measles': self._CHBOX_measles,
496 u'meningococcus A': self._CHBOX_menA,
497 u'meningococcus C': self._CHBOX_menC,
498 u'meningococcus W': self._CHBOX_menW,
499 u'meningococcus Y': self._CHBOX_menY,
500 u'mumps': self._CHBOX_mumps,
501 u'pertussis': self._CHBOX_pertussis,
502 u'pneumococcus': self._CHBOX_pneumococcus,
503 u'poliomyelitis': self._CHBOX_polio,
504 u'rabies': self._CHBOX_rabies,
505 u'rubella': self._CHBOX_rubella,
506 u'tetanus': self._CHBOX_tetanus,
507 u'tick-borne meningoencephalitis': self._CHBOX_fsme,
508 u'yellow fever': self._CHBOX_yellow_fever,
509 u'yersinia pestis': self._CHBOX_yersinia_pestis
510 }
511
513 for field in self.__dict__.keys():
514 if field.startswith('_CHBOX_'):
515 self.__dict__[field].Enable()
516 self.Enable()
517
519 for field in self.__dict__.keys():
520 if field.startswith('_CHBOX_'):
521 self.__dict__[field].Disable()
522 self.Disable()
523
525 for field in self.__dict__.keys():
526 if field.startswith('_CHBOX_'):
527 self.__dict__[field].SetValue(False)
528
529 - def select(self, indications=None):
530 for indication in indications:
531 self.__indication2field[indication].SetValue(True)
532
534 indications = []
535 for indication in self.__indication2field.keys():
536 if self.__indication2field[indication].IsChecked():
537 indications.append(indication)
538 return indications
539
540 selected_indications = property(_get_selected_indications, lambda x:x)
541
543 for indication in self.__indication2field.keys():
544 if self.__indication2field[indication].IsChecked():
545 return True
546 return False
547
548 has_selection = property(_get_has_selection, lambda x:x)
549
550
551 from Gnumed.wxGladeWidgets import wxgVaccinationEAPnl
552
553 -class cVaccinationEAPnl(wxgVaccinationEAPnl.wxgVaccinationEAPnl, gmEditArea.cGenericEditAreaMixin):
554 """
555 - warn on apparent duplicates
556 - ask if "missing" (= previous, non-recorded) vaccinations
557 should be estimated and saved (add note "auto-generated")
558
559 Batch No (http://www.fao.org/docrep/003/v9952E12.htm)
560 """
578
585
587
588 vaccine = self._PRW_vaccine.GetData(as_instance=True)
589
590
591 if self.mode == u'edit':
592 self._PNL_indications.clear_all()
593 if vaccine is None:
594 self._PRW_batch.unset_context(context = 'pk_vaccine')
595 else:
596 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine'])
597 self._PNL_indications.select(indications = vaccine['indications'])
598 self._PNL_indications.disable_all()
599
600
601 else:
602 if vaccine is None:
603 self._PRW_batch.unset_context(context = 'pk_vaccine')
604 self._PNL_indications.enable_all()
605 else:
606 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine'])
607 self._PNL_indications.clear_all()
608 self._PNL_indications.select(indications = vaccine['indications'])
609 self._PNL_indications.disable_all()
610
612 if self._PRW_reaction.GetValue().strip() == u'':
613 self._BTN_report.Enable(False)
614 else:
615 self._BTN_report.Enable(True)
616
617
618
620
621 has_errors = False
622
623 if not self._DP_date_given.is_valid_timestamp(allow_none = False):
624 has_errors = True
625
626 vaccine = self._PRW_vaccine.GetData(as_instance = True)
627
628
629 if self.mode == u'edit':
630 if vaccine is None:
631 has_errors = True
632 self._PRW_vaccine.display_as_valid(False)
633 else:
634 self._PRW_vaccine.display_as_valid(True)
635 self._PNL_indications.clear_all()
636 self._PNL_indications.select(indications = vaccine['indications'])
637 self._PNL_indications.disable_all()
638
639 else:
640 if vaccine is None:
641 if self._PNL_indications.has_selection:
642 self._PRW_vaccine.display_as_valid(True)
643 else:
644 has_errors = True
645 self._PRW_vaccine.display_as_valid(False)
646 else:
647 self._PRW_vaccine.display_as_valid(True)
648
649 if self._PRW_batch.GetValue().strip() == u'':
650 has_errors = True
651 self._PRW_batch.display_as_valid(False)
652 else:
653 self._PRW_batch.display_as_valid(True)
654
655 if self._PRW_episode.GetValue().strip() == u'':
656 self._PRW_episode.SetText(value = _('prevention'))
657
658 return (has_errors is False)
659
661
662 vaccine = self._PRW_vaccine.GetData()
663 if vaccine is None:
664 data = self.__save_new_from_indications()
665 else:
666 data = self.__save_new_from_vaccine(vaccine = vaccine)
667
668
669
670
671 self.data = data
672
673 return True
674
688
713
715
716 if self._CHBOX_anamnestic.GetValue() is True:
717 self.data['soap_cat'] = u's'
718 else:
719 self.data['soap_cat'] = u'p'
720
721 self.data['date_given'] = self._DP_date_given.get_pydt()
722 self.data['pk_vaccine'] = self._PRW_vaccine.GetData()
723 self.data['batch_no'] = self._PRW_batch.GetValue().strip()
724 self.data['pk_episode'] = self._PRW_episode.GetData(can_create = True, is_open = False)
725 self.data['site'] = self._PRW_site.GetValue().strip()
726 self.data['pk_provider'] = self._PRW_provider.GetData()
727 self.data['reaction'] = self._PRW_reaction.GetValue().strip()
728 self.data['comment'] = self._TCTRL_comment.GetValue().strip()
729
730 self.data.save()
731
732 return True
733
751
776
797
819
820
821
822
824
826 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER)
827 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
828 self.__pat = gmPerson.gmCurrentPatient()
829
830 self.ID_VaccinatedIndicationsList = wx.NewId()
831 self.ID_VaccinationsPerRegimeList = wx.NewId()
832 self.ID_MissingShots = wx.NewId()
833 self.ID_ActiveSchedules = wx.NewId()
834 self.__do_layout()
835 self.__register_interests()
836 self.__reset_ui_content()
837
839
840
841
842 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _(" IMMUNISATIONS "))
843 self.editarea = cVaccinationEditArea(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
844
845
846
847
848
849 indications_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Indications"))
850 vaccinations_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Vaccinations"))
851 schedules_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Active Schedules"))
852 szr_MiddleCap = wx.BoxSizer(wx.HORIZONTAL)
853 szr_MiddleCap.Add(indications_heading, 4, wx.EXPAND)
854 szr_MiddleCap.Add(vaccinations_heading, 6, wx.EXPAND)
855 szr_MiddleCap.Add(schedules_heading, 10, wx.EXPAND)
856
857
858 self.LBOX_vaccinated_indications = wx.ListBox(
859 parent = self,
860 id = self.ID_VaccinatedIndicationsList,
861 choices = [],
862 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER
863 )
864 self.LBOX_vaccinated_indications.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
865
866
867
868 self.LBOX_given_shots = wx.ListBox(
869 parent = self,
870 id = self.ID_VaccinationsPerRegimeList,
871 choices = [],
872 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER
873 )
874 self.LBOX_given_shots.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
875
876 self.LBOX_active_schedules = wx.ListBox (
877 parent = self,
878 id = self.ID_ActiveSchedules,
879 choices = [],
880 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER
881 )
882 self.LBOX_active_schedules.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
883
884 szr_MiddleLists = wx.BoxSizer(wx.HORIZONTAL)
885 szr_MiddleLists.Add(self.LBOX_vaccinated_indications, 4, wx.EXPAND)
886 szr_MiddleLists.Add(self.LBOX_given_shots, 6, wx.EXPAND)
887 szr_MiddleLists.Add(self.LBOX_active_schedules, 10, wx.EXPAND)
888
889
890
891
892 missing_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Missing Immunisations"))
893 szr_BottomCap = wx.BoxSizer(wx.HORIZONTAL)
894 szr_BottomCap.Add(missing_heading, 1, wx.EXPAND)
895
896 self.LBOX_missing_shots = wx.ListBox (
897 parent = self,
898 id = self.ID_MissingShots,
899 choices = [],
900 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER
901 )
902 self.LBOX_missing_shots.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
903
904 szr_BottomLists = wx.BoxSizer(wx.HORIZONTAL)
905 szr_BottomLists.Add(self.LBOX_missing_shots, 1, wx.EXPAND)
906
907
908 pnl_AlertCaption = gmTerryGuiParts.cAlertCaption(self, -1, _(' Alerts '))
909
910
911
912
913 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
914 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
915 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
916 self.mainsizer.Add(szr_MiddleCap, 0, wx.EXPAND)
917 self.mainsizer.Add(szr_MiddleLists, 4, wx.EXPAND)
918 self.mainsizer.Add(szr_BottomCap, 0, wx.EXPAND)
919 self.mainsizer.Add(szr_BottomLists, 4, wx.EXPAND)
920 self.mainsizer.Add(pnl_AlertCaption, 0, wx.EXPAND)
921
922 self.SetAutoLayout(True)
923 self.SetSizer(self.mainsizer)
924 self.mainsizer.Fit(self)
925
927
928 wx.EVT_SIZE(self, self.OnSize)
929 wx.EVT_LISTBOX(self, self.ID_VaccinatedIndicationsList, self._on_vaccinated_indication_selected)
930 wx.EVT_LISTBOX_DCLICK(self, self.ID_VaccinationsPerRegimeList, self._on_given_shot_selected)
931 wx.EVT_LISTBOX_DCLICK(self, self.ID_MissingShots, self._on_missing_shot_selected)
932
933
934
935 gmDispatcher.connect(signal= u'post_patient_selection', receiver=self._schedule_data_reget)
936 gmDispatcher.connect(signal= u'vaccinations_updated', receiver=self._schedule_data_reget)
937
938
939
941 w, h = event.GetSize()
942 self.mainsizer.SetDimension (0, 0, w, h)
943
945 """Paste previously given shot into edit area.
946 """
947 self.editarea.set_data(aVacc=event.GetClientData())
948
950 self.editarea.set_data(aVacc = event.GetClientData())
951
953 """Update right hand middle list to show vaccinations given for selected indication."""
954 ind_list = event.GetEventObject()
955 selected_item = ind_list.GetSelection()
956 ind = ind_list.GetClientData(selected_item)
957
958 self.LBOX_given_shots.Set([])
959 emr = self.__pat.get_emr()
960 shots = emr.get_vaccinations(indications = [ind])
961
962 for shot in shots:
963 if shot['is_booster']:
964 marker = 'B'
965 else:
966 marker = '#%s' % shot['seq_no']
967 label = '%s - %s: %s' % (marker, shot['date'].strftime('%m/%Y'), shot['vaccine'])
968 self.LBOX_given_shots.Append(label, shot)
969
971
972 self.editarea.set_data()
973
974 self.LBOX_vaccinated_indications.Clear()
975 self.LBOX_given_shots.Clear()
976 self.LBOX_active_schedules.Clear()
977 self.LBOX_missing_shots.Clear()
978
980
981 self.LBOX_vaccinated_indications.Clear()
982 self.LBOX_given_shots.Clear()
983 self.LBOX_active_schedules.Clear()
984 self.LBOX_missing_shots.Clear()
985
986 emr = self.__pat.get_emr()
987
988 t1 = time.time()
989
990
991
992 status, indications = emr.get_vaccinated_indications()
993
994
995
996 for indication in indications:
997 self.LBOX_vaccinated_indications.Append(indication[1], indication[0])
998
999
1000 print "vaccinated indications took", time.time()-t1, "seconds"
1001
1002 t1 = time.time()
1003
1004 scheds = emr.get_scheduled_vaccination_regimes()
1005 if scheds is None:
1006 label = _('ERROR: cannot retrieve active vaccination schedules')
1007 self.LBOX_active_schedules.Append(label)
1008 elif len(scheds) == 0:
1009 label = _('no active vaccination schedules')
1010 self.LBOX_active_schedules.Append(label)
1011 else:
1012 for sched in scheds:
1013 label = _('%s for %s (%s shots): %s') % (sched['regime'], sched['l10n_indication'], sched['shots'], sched['comment'])
1014 self.LBOX_active_schedules.Append(label)
1015 print "active schedules took", time.time()-t1, "seconds"
1016
1017 t1 = time.time()
1018
1019 missing_shots = emr.get_missing_vaccinations()
1020 print "getting missing shots took", time.time()-t1, "seconds"
1021 if missing_shots is None:
1022 label = _('ERROR: cannot retrieve due/overdue vaccinations')
1023 self.LBOX_missing_shots.Append(label, None)
1024 return True
1025
1026 due_template = _('%.0d weeks left: shot %s for %s in %s, due %s (%s)')
1027 overdue_template = _('overdue %.0dyrs %.0dwks: shot %s for %s in schedule "%s" (%s)')
1028 for shot in missing_shots['due']:
1029 if shot['overdue']:
1030 years, days_left = divmod(shot['amount_overdue'].days, 364.25)
1031 weeks = days_left / 7
1032
1033 label = overdue_template % (
1034 years,
1035 weeks,
1036 shot['seq_no'],
1037 shot['l10n_indication'],
1038 shot['regime'],
1039 shot['vacc_comment']
1040 )
1041 self.LBOX_missing_shots.Append(label, shot)
1042 else:
1043
1044 label = due_template % (
1045 shot['time_left'].days / 7,
1046 shot['seq_no'],
1047 shot['indication'],
1048 shot['regime'],
1049 shot['latest_due'].strftime('%m/%Y'),
1050 shot['vacc_comment']
1051 )
1052 self.LBOX_missing_shots.Append(label, shot)
1053
1054 lbl_template = _('due now: booster for %s in schedule "%s" (%s)')
1055 for shot in missing_shots['boosters']:
1056
1057 label = lbl_template % (
1058 shot['l10n_indication'],
1059 shot['regime'],
1060 shot['vacc_comment']
1061 )
1062 self.LBOX_missing_shots.Append(label, shot)
1063 print "displaying missing shots took", time.time()-t1, "seconds"
1064
1065 return True
1066
1067 - def _on_post_patient_selection(self, **kwargs):
1069
1070
1071
1072
1073
1074
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 if __name__ == "__main__":
1087
1088 if len(sys.argv) < 2:
1089 sys.exit()
1090
1091 if sys.argv[1] != u'test':
1092 sys.exit()
1093
1094 app = wxPyWidgetTester(size = (600, 600))
1095 app.SetWidget(cImmunisationsPanel, -1)
1096 app.MainLoop()
1097
1098