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
33 "Fake wrapper, will always call the allergy manager."
34
35 dlg = cAllergyManagerDlg(parent = parent, id = -1)
36 result = dlg.ShowModal()
37 dlg.DestroyLater()
38 if result != wx.ID_OK:
39 return False
40
41 return True
42
43
44 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaPnl
45
47
49 wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl.__init__(self, *args, **kwargs)
50
51 try:
52 self.__allergy = kwargs['allergy']
53 except KeyError:
54 self.__allergy = None
55
56 mp = gmMatchProvider.cMatchProvider_SQL2 (
57 queries = ["""
58 select substance, substance
59 from clin.allergy
60 where substance %(fragment_condition)s
61
62 union
63
64 select generics, generics
65 from clin.allergy
66 where generics %(fragment_condition)s
67
68 union
69
70 select allergene, allergene
71 from clin.allergy
72 where allergene %(fragment_condition)s
73
74 union
75
76 select atc_code, atc_code
77 from clin.allergy
78 where atc_code %(fragment_condition)s
79 """
80 ]
81 )
82 mp.setThresholds(2, 3, 5)
83 self._PRW_trigger.matcher = mp
84
85 mp = gmMatchProvider.cMatchProvider_SQL2 (
86 queries = ["""
87 select narrative, narrative
88 from clin.allergy
89 where narrative %(fragment_condition)s
90 """]
91 )
92 mp.setThresholds(2, 3, 5)
93 self._PRW_reaction.matcher = mp
94 self._PRW_reaction.enable_default_spellchecker()
95
96
97
98
99 self.refresh()
100
101
102
104 self.__allergy = None
105 return self.refresh()
106
148
168
169 - def save(self, can_create=True):
170 if not self.__is_valid_for_save():
171 return False
172
173 if self.__allergy is None:
174 if not can_create:
175 gmDispatcher.send(signal='statustext', msg=_('Creating new allergy not allowed.'))
176 return False
177
178 pat = gmPerson.gmCurrentPatient()
179 emr = pat.emr
180
181 if self._RBTN_type_allergy.GetValue():
182 allg_type = 'allergy'
183 else:
184 allg_type = 'sensitivity'
185 self.__allergy = emr.add_allergy (
186 allergene = self._PRW_trigger.GetValue().strip(),
187 allg_type = allg_type
188 )
189
190
191 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt()
192 self.__allergy['allergene'] = self._PRW_trigger.GetValue().strip()
193
194 self.__allergy['generic_specific'] = (True and self._ChBOX_generic_specific.GetValue())
195 self.__allergy['reaction'] = self._PRW_reaction.GetValue().strip()
196 self.__allergy['definite'] = (True and self._ChBOX_definite.GetValue())
197 if self._RBTN_type_allergy.GetValue():
198 self.__allergy['pk_type'] = 'allergy'
199 else:
200 self.__allergy['pk_type'] = 'sensitivity'
201
202 self.__allergy.save_payload()
203
204 return True
205
206
207 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaDlg
208
210
212
213 try:
214 allergy = kwargs['allergy']
215 del kwargs['allergy']
216 except KeyError:
217 allergy = None
218
219 wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg.__init__(self, *args, **kwargs)
220
221 if allergy is None:
222
223 self._BTN_clear.SetLabel(_('&Clear'))
224 else:
225
226 self._BTN_clear.SetLabel(_('&Restore'))
227
228 self._PNL_edit_area.refresh(allergy = allergy)
229
236
239
240
241 from Gnumed.wxGladeWidgets import wxgAllergyManagerDlg
242
244
259
260
261
262
264 self._LCTRL_allergies.set_columns (columns = [
265 _('Type'),
266 _('Certainty'),
267 _('Trigger'),
268 _('Reaction')
269 ])
270
272
273 pat = gmPerson.gmCurrentPatient()
274 emr = pat.emr
275 state = emr.allergy_state
276
277 self._TXT_current_state.SetLabel(state.state_string)
278
279 if state['last_confirmed'] is None:
280 self._TXT_last_confirmed.SetLabel(_('<allergy state unasked>'))
281 else:
282 self._TXT_last_confirmed.SetLabel(state['last_confirmed'].strftime('%x %H:%M'))
283
284 if state['has_allergy'] is None:
285 self._RBTN_unknown.SetValue(True)
286 self._RBTN_none.SetValue(False)
287 self._RBTN_some.SetValue(False)
288
289 self._RBTN_unknown.Enable(True)
290 self._RBTN_none.Enable(True)
291
292 elif state['has_allergy'] == 0:
293 self._RBTN_unknown.SetValue(False)
294 self._RBTN_none.SetValue(True)
295 self._RBTN_some.SetValue(False)
296
297 self._RBTN_unknown.Enable(True)
298 self._RBTN_none.Enable(True)
299
300 elif state['has_allergy'] == 1:
301 self._RBTN_unknown.SetValue(False)
302 self._RBTN_none.SetValue(False)
303 self._RBTN_some.SetValue(True)
304
305 self._RBTN_unknown.Enable(True)
306 self._RBTN_none.Enable(False)
307
308 else:
309 self._RBTN_unknown.SetValue(True)
310 self._RBTN_none.SetValue(False)
311 self._RBTN_some.SetValue(False)
312
313 self._RBTN_unknown.Enable(True)
314 self._RBTN_none.Enable(True)
315
316 gmDispatcher.send(signal='statustext', msg=_('invalid allergy state [%s]') % state, beep=True)
317
318 if state['comment'] is not None:
319 self._TCTRL_state_comment.SetValue(state['comment'])
320
322
323 pat = gmPerson.gmCurrentPatient()
324 emr = pat.emr
325 allergies = emr.get_allergies()
326 no_of_allergies = len(allergies)
327
328
329 self._LCTRL_allergies.DeleteAllItems()
330 if no_of_allergies > 0:
331 emr.allergy_state = 1
332
333 for allergy in allergies:
334 row_idx = self._LCTRL_allergies.InsertItem(no_of_allergies, label = allergy['l10n_type'])
335 if allergy['definite']:
336 label = _('definite')
337 else:
338 label = ''
339 self._LCTRL_allergies.SetItem(index = row_idx, column = 1, label = label)
340 self._LCTRL_allergies.SetItem(index = row_idx, column = 2, label = allergy['descriptor'])
341 self._LCTRL_allergies.SetItem(index = row_idx, column = 3, label = gmTools.coalesce(allergy['reaction'], ''))
342 self._LCTRL_allergies.set_data(data=allergies)
343
344 self._LCTRL_allergies.Enable(True)
345 self._RBTN_some.SetValue(True)
346 self._RBTN_unknown.Enable(False)
347 self._RBTN_none.Enable(False)
348 else:
349 self._LCTRL_allergies.Enable(False)
350 self._RBTN_unknown.Enable(True)
351 self._RBTN_none.Enable(True)
352
353 self._LCTRL_allergies.set_column_widths (widths = [
354 wx.LIST_AUTOSIZE,
355 wx.LIST_AUTOSIZE,
356 wx.LIST_AUTOSIZE,
357 wx.LIST_AUTOSIZE
358 ])
359
360 self._PNL_edit_area.clear()
361 self._BTN_delete.Enable(False)
362
363
364
370
371
377
378
394
396 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True)
397 if allergy is None:
398 return
399 self._PNL_edit_area.refresh(allergy = allergy)
400 self._BTN_delete.Enable(True)
401 self._LBL_message.SetLabel(_('Edit the selected allergy item:'))
402
441
455
456
458 """Allergy details panel.
459
460 This panel will hold all the allergy details and
461 allow entry of those details via the editing area.
462 """
463
471
473
474 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
475 self.editarea = gmAllergyEditArea(self, -1)
476
477
478
479 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
480
481
482 self.LCTRL_allergies = wx.ListCtrl (
483 parent = self,
484 id = ID_ALLERGY_LIST,
485 pos = wx.DefaultPosition,
486 size = wx.DefaultSize,
487 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL
488 )
489 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
490 self.LCTRL_allergies.InsertColumn(0, _("Type"))
491 self.LCTRL_allergies.InsertColumn(1, _("Status"))
492 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class"))
493 self.LCTRL_allergies.InsertColumn(3, _("Substance"))
494 self.LCTRL_allergies.InsertColumn(4, _("Generics"))
495 self.LCTRL_allergies.InsertColumn(5, _("Reaction"))
496
497
498 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
499
500
501 self.class_notes = wx.TextCtrl (
502 self,
503 -1,
504 "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.",
505 size = (200, 100),
506 style = wx.TE_MULTILINE | wx.TE_READONLY
507 )
508 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
509
510
511 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
512 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
513 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
514
515 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND)
516 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND)
517 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND)
518 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND)
519
520 self.SetAutoLayout(True)
521 self.SetSizer(self.mainsizer)
522 self.mainsizer.Fit(self)
523
525 self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._on_allergy_activated)
526
527
528
529 gmDispatcher.connect(signal = 'post_patient_selection', receiver=self._schedule_data_reget)
530
531
533 self.editarea.set_data()
534 self.LCTRL_allergies.DeleteAllItems()
535
537 if not self.__pat.connected:
538 return False
539
540 self.LCTRL_allergies.DeleteAllItems()
541
542 emr = self.__pat.emr
543 allergies = emr.get_allergies()
544 if allergies is None:
545 return False
546 for list_line in range(len(allergies)):
547 allg = allergies[list_line]
548 list_line = self.LCTRL_allergies.InsertItem(list_line, allg['l10n_type'])
549
550 if allg['definite']:
551 self.LCTRL_allergies.SetItem(list_line, 1, _('definite'))
552 else:
553 self.LCTRL_allergies.SetItem(list_line, 1, _('likely'))
554 if allg['atc_code'] is not None:
555 self.LCTRL_allergies.SetItem(list_line, 2, allg['atc_code'])
556 self.LCTRL_allergies.SetItem(list_line, 3, allg['substance'])
557 if allg['generics'] is not None:
558 self.LCTRL_allergies.SetItem(list_line, 4, allg['generics'])
559 self.LCTRL_allergies.SetItem(list_line, 5, allg['reaction'])
560 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy'])
561 for col in range(5):
562 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE)
563
564 return True
565
571
572
573
574 if __name__ == "__main__":
575
576 from Gnumed.wxpython import gmPatSearchWidgets
577
578 gmI18N.activate_locale()
579 gmI18N.install_domain(domain='gnumed')
580
581
583 app = wx.PyWidgetTester(size = (600, 600))
584 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1)
585 dlg.ShowModal()
586
587
588
589
590 return
591
593 app = wx.PyWidgetTester(size = (800, 600))
594 dlg = cAllergyManagerDlg(parent=app.frame, id=-1)
595 dlg.ShowModal()
596 return
597
598 if len(sys.argv) > 1 and sys.argv[1] == 'test':
599
600 pat = gmPersonSearch.ask_for_patient()
601 if pat is None:
602 sys.exit(0)
603 gmPatSearchWidgets.set_active_patient(pat)
604
605
606 test_allergy_manager_dlg()
607
608
609
610
611
612