1 """GNUmed allergy related widgets."""
2
3 __author__ = "R.Terry <rterry@gnumed.net>, H.Herb <hherb@gnumed.net>, K.Hilbert <Karsten.Hilbert@gmx.net>"
4 __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
5
6 import sys, time, datetime as pyDT, logging
7
8
9 import wx
10
11
12 if __name__ == '__main__':
13 sys.path.insert(0, '../../')
14 from Gnumed.pycommon import gmDispatcher
15 from Gnumed.pycommon import gmI18N
16 from Gnumed.pycommon import gmDateTime
17 from Gnumed.pycommon import gmTools
18 from Gnumed.pycommon import gmMatchProvider
19
20 from Gnumed.business import gmPerson
21 from Gnumed.business import gmAllergy
22 from Gnumed.business import gmPersonSearch
23
24 from Gnumed.wxpython import gmDateTimeInput
25 from Gnumed.wxpython import gmTerryGuiParts
26 from Gnumed.wxpython import gmRegetMixin
27
28
29 _log = logging.getLogger('gm.ui')
30
31
32 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaPnl
33
35
37 wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl.__init__(self, *args, **kwargs)
38
39 try:
40 self.__allergy = kwargs['allergy']
41 except KeyError:
42 self.__allergy = None
43
44 mp = gmMatchProvider.cMatchProvider_SQL2 (
45 queries = [u"""
46 select substance, substance
47 from clin.allergy
48 where substance %(fragment_condition)s
49
50 union
51
52 select generics, generics
53 from clin.allergy
54 where generics %(fragment_condition)s
55
56 union
57
58 select allergene, allergene
59 from clin.allergy
60 where allergene %(fragment_condition)s
61
62 union
63
64 select atc_code, atc_code
65 from clin.allergy
66 where atc_code %(fragment_condition)s
67 """
68 ]
69 )
70 mp.setThresholds(2, 3, 5)
71 self._PRW_trigger.matcher = mp
72
73 mp = gmMatchProvider.cMatchProvider_SQL2 (
74 queries = [u"""
75 select narrative, narrative
76 from clin.allergy
77 where narrative %(fragment_condition)s
78 """]
79 )
80 mp.setThresholds(2, 3, 5)
81 self._PRW_reaction.matcher = mp
82 self._PRW_reaction.enable_default_spellchecker()
83
84
85
86
87 self.refresh()
88
89
90
92 self.__allergy = None
93 return self.refresh()
94
136
156
157 - def save(self, can_create=True):
158 if not self.__is_valid_for_save():
159 return False
160
161 if self.__allergy is None:
162 if not can_create:
163 gmDispatcher.send(signal='statustext', msg=_('Creating new allergy not allowed.'))
164 return False
165
166 pat = gmPerson.gmCurrentPatient()
167 emr = pat.get_emr()
168
169 if self._RBTN_type_allergy.GetValue():
170 allg_type = 'allergy'
171 else:
172 allg_type = 'sensitivity'
173 self.__allergy = emr.add_allergy (
174 allergene = self._PRW_trigger.GetValue().strip(),
175 allg_type = allg_type
176 )
177
178
179 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt()
180 self.__allergy['allergene'] = self._PRW_trigger.GetValue().strip()
181
182 self.__allergy['generic_specific'] = (True and self._ChBOX_generic_specific.GetValue())
183 self.__allergy['reaction'] = self._PRW_reaction.GetValue().strip()
184 self.__allergy['definite'] = (True and self._ChBOX_definite.GetValue())
185 if self._RBTN_type_allergy.GetValue():
186 self.__allergy['pk_type'] = 'allergy'
187 else:
188 self.__allergy['pk_type'] = 'sensitivity'
189
190 self.__allergy.save_payload()
191
192 return True
193
194
195 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaDlg
196
198
200
201 try:
202 allergy = kwargs['allergy']
203 del kwargs['allergy']
204 except KeyError:
205 allergy = None
206
207 wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg.__init__(self, *args, **kwargs)
208
209 if allergy is None:
210
211 self._BTN_clear.SetLabel(_('&Clear'))
212 else:
213
214 self._BTN_clear.SetLabel(_('&Restore'))
215
216 self._PNL_edit_area.refresh(allergy = allergy)
217
224
227
228
229 from Gnumed.wxGladeWidgets import wxgAllergyManagerDlg
230
232
247
248
249
251 self._LCTRL_allergies.set_columns (columns = [
252 _('Type'),
253 _('Certainty'),
254 _('Trigger'),
255 _('Reaction')
256 ])
257
259
260 pat = gmPerson.gmCurrentPatient()
261 emr = pat.get_emr()
262 state = emr.allergy_state
263
264 self._TXT_current_state.SetLabel(state.state_string)
265
266 if state['last_confirmed'] is None:
267 self._TXT_last_confirmed.SetLabel(_('<allergy state unasked>'))
268 else:
269 self._TXT_last_confirmed.SetLabel(state['last_confirmed'].strftime('%x %H:%M'))
270
271 if state['has_allergy'] is None:
272 self._RBTN_unknown.SetValue(True)
273 self._RBTN_none.SetValue(False)
274 self._RBTN_some.SetValue(False)
275
276 self._RBTN_unknown.Enable(True)
277 self._RBTN_none.Enable(True)
278
279 elif state['has_allergy'] == 0:
280 self._RBTN_unknown.SetValue(False)
281 self._RBTN_none.SetValue(True)
282 self._RBTN_some.SetValue(False)
283
284 self._RBTN_unknown.Enable(True)
285 self._RBTN_none.Enable(True)
286
287 elif state['has_allergy'] == 1:
288 self._RBTN_unknown.SetValue(False)
289 self._RBTN_none.SetValue(False)
290 self._RBTN_some.SetValue(True)
291
292 self._RBTN_unknown.Enable(True)
293 self._RBTN_none.Enable(False)
294
295 else:
296 self._RBTN_unknown.SetValue(True)
297 self._RBTN_none.SetValue(False)
298 self._RBTN_some.SetValue(False)
299
300 self._RBTN_unknown.Enable(True)
301 self._RBTN_none.Enable(True)
302
303 gmDispatcher.send(signal=u'statustext', msg=_('invalid allergy state [%s]') % state, beep=True)
304
305 if state['comment'] is not None:
306 self._TCTRL_state_comment.SetValue(state['comment'])
307
309
310 pat = gmPerson.gmCurrentPatient()
311 emr = pat.get_emr()
312 allergies = emr.get_allergies()
313 no_of_allergies = len(allergies)
314
315
316 self._LCTRL_allergies.DeleteAllItems()
317 if no_of_allergies > 0:
318 emr.allergy_state = 1
319
320 for allergy in allergies:
321 row_idx = self._LCTRL_allergies.InsertStringItem(no_of_allergies, label = allergy['l10n_type'])
322 if allergy['definite']:
323 label = _('definite')
324 else:
325 label = u''
326 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 1, label = label)
327 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 2, label = allergy['descriptor'])
328 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 3, label = gmTools.coalesce(allergy['reaction'], u''))
329 self._LCTRL_allergies.set_data(data=allergies)
330
331 self._LCTRL_allergies.Enable(True)
332 self._RBTN_some.SetValue(True)
333 self._RBTN_unknown.Enable(False)
334 self._RBTN_none.Enable(False)
335 else:
336 self._LCTRL_allergies.Enable(False)
337 self._RBTN_unknown.Enable(True)
338 self._RBTN_none.Enable(True)
339
340 self._LCTRL_allergies.set_column_widths (widths = [
341 wx.LIST_AUTOSIZE,
342 wx.LIST_AUTOSIZE,
343 wx.LIST_AUTOSIZE,
344 wx.LIST_AUTOSIZE
345 ])
346
347 self._PNL_edit_area.clear()
348 self._BTN_delete.Enable(False)
349
350
351
357
363
379
381 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True)
382 if allergy is None:
383 return
384 self._PNL_edit_area.refresh(allergy = allergy)
385 self._BTN_delete.Enable(True)
386 self._LBL_message.SetLabel(_('Edit the selected allergy item:'))
387
426
440
442 """Allergy details panel.
443
444 This panel will hold all the allergy details and
445 allow entry of those details via the editing area.
446 """
447
455
457
458 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
459 self.editarea = gmAllergyEditArea(self, -1)
460
461
462
463 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
464
465
466 self.LCTRL_allergies = wx.ListCtrl (
467 parent = self,
468 id = ID_ALLERGY_LIST,
469 pos = wx.DefaultPosition,
470 size = wx.DefaultSize,
471 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL
472 )
473 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
474 self.LCTRL_allergies.InsertColumn(0, _("Type"))
475 self.LCTRL_allergies.InsertColumn(1, _("Status"))
476 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class"))
477 self.LCTRL_allergies.InsertColumn(3, _("Substance"))
478 self.LCTRL_allergies.InsertColumn(4, _("Generics"))
479 self.LCTRL_allergies.InsertColumn(5, _("Reaction"))
480
481
482 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
483
484
485 self.class_notes = wx.TextCtrl (
486 self,
487 -1,
488 "A member of a new class of nonsteroidal anti-inflammatory agents (COX-2 selective NSAIDs) which have a mechanism of action that inhibits prostaglandin synthesis primarily by inhibition of cyclooxygenase 2 (COX-2). At therapeutic doses these have no effect on prostanoids synthesised by activation of COX-1 thereby not interfering with normal COX-1 related physiological processes in tissues, particularly the stomach, intestine and platelets.",
489 size = (200, 100),
490 style = wx.TE_MULTILINE | wx.TE_READONLY
491 )
492 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
493
494
495 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
496 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
497 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
498
499 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND)
500 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND)
501 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND)
502 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND)
503
504 self.SetAutoLayout(True)
505 self.SetSizer(self.mainsizer)
506 self.mainsizer.Fit(self)
507
509 wx.EVT_LIST_ITEM_ACTIVATED(self, ID_ALLERGY_LIST, self._on_allergy_activated)
510
511
512 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
513
514
516 self.editarea.set_data()
517 self.LCTRL_allergies.DeleteAllItems()
518
520 if not self.__pat.connected:
521 return False
522
523 self.LCTRL_allergies.DeleteAllItems()
524
525 emr = self.__pat.get_emr()
526 allergies = emr.get_allergies()
527 if allergies is None:
528 return False
529 for list_line in range(len(allergies)):
530 allg = allergies[list_line]
531 list_line = self.LCTRL_allergies.InsertStringItem(list_line, allg['l10n_type'])
532
533 if allg['definite']:
534 self.LCTRL_allergies.SetStringItem(list_line, 1, _('definite'))
535 else:
536 self.LCTRL_allergies.SetStringItem(list_line, 1, _('likely'))
537 if allg['atc_code'] is not None:
538 self.LCTRL_allergies.SetStringItem(list_line, 2, allg['atc_code'])
539 self.LCTRL_allergies.SetStringItem(list_line, 3, allg['substance'])
540 if allg['generics'] is not None:
541 self.LCTRL_allergies.SetStringItem(list_line, 4, allg['generics'])
542 self.LCTRL_allergies.SetStringItem(list_line, 5, allg['reaction'])
543 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy'])
544 for col in range(5):
545 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE)
546
547 return True
548
554
555
556
557 if __name__ == "__main__":
558
559 from Gnumed.wxpython import gmPatSearchWidgets
560
561 gmI18N.activate_locale()
562 gmI18N.install_domain(domain='gnumed')
563
564
566 app = wx.PyWidgetTester(size = (600, 600))
567 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1)
568 dlg.ShowModal()
569
570
571
572
573 return
574
576 app = wx.PyWidgetTester(size = (800, 600))
577 dlg = cAllergyManagerDlg(parent=app.frame, id=-1)
578 dlg.ShowModal()
579 return
580
581 if len(sys.argv) > 1 and sys.argv[1] == 'test':
582
583 pat = gmPersonSearch.ask_for_patient()
584 if pat is None:
585 sys.exit(0)
586 gmPatSearchWidgets.set_active_patient(pat)
587
588
589 test_allergy_manager_dlg()
590
591
592
593
594
595