| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed waiting list widgets."""
2 #================================================================
3 __author__ = 'karsten.hilbert@gmx.net'
4 __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
5
6 # stdlib
7 import logging
8 import sys
9
10
11 # 3rd party
12 import wx
13
14 # GNUmed
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17
18 from Gnumed.pycommon import gmDispatcher
19 from Gnumed.pycommon import gmTools
20 from Gnumed.pycommon import gmMatchProvider
21 from Gnumed.pycommon import gmI18N
22 from Gnumed.pycommon import gmExceptions
23 from Gnumed.pycommon import gmDateTime
24
25 from Gnumed.business import gmPraxis
26 from Gnumed.business import gmPerson
27
28 from Gnumed.wxpython import gmEditArea
29 from Gnumed.wxpython import gmPhraseWheel
30 from Gnumed.wxpython import gmRegetMixin
31 from Gnumed.wxpython import gmPatSearchWidgets
32 from Gnumed.wxpython import gmGuiHelpers
33
34
35 _log = logging.getLogger('gm.ui')
36 #============================================================
37 # waiting list widgets
38 #============================================================
40
42
43 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
44
45 mp = gmMatchProvider.cMatchProvider_FixedList(aSeq = [])
46 mp.setThresholds(1, 2, 2)
47 self.matcher = mp
48 self.selection_only = False
49
50 #--------------------------------------------------------
53
54 #============================================================
56 if parent is None:
57 parent = wx.GetApp().GetTopWindow()
58 ea = cWaitingListEntryEditAreaPnl(parent, -1, patient = gmTools.bool2subst((entry is None), patient, None))
59 ea.data = entry
60 ea.mode = gmTools.coalesce(entry, 'new', 'edit')
61 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = True)
62 dlg.SetTitle(gmTools.coalesce(entry, _('Adding new waiting list entry'), _('Editing waiting list entry')))
63 if dlg.ShowModal() == wx.ID_OK:
64 dlg.DestroyLater()
65 return True
66 dlg.DestroyLater()
67 return False
68
69 #============================================================
70 from Gnumed.wxGladeWidgets import wxgWaitingListEntryEditAreaPnl
71
72 -class cWaitingListEntryEditAreaPnl(wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
73
75
76 try:
77 self.patient = kwargs['patient']
78 del kwargs['patient']
79 except KeyError:
80 self.patient = None
81
82 try:
83 data = kwargs['entry']
84 del kwargs['entry']
85 except KeyError:
86 data = None
87
88 wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl.__init__(self, *args, **kwargs)
89 gmEditArea.cGenericEditAreaMixin.__init__(self)
90
91 if data is None:
92 self.mode = 'new'
93 else:
94 self.data = data
95 self.mode = 'edit'
96
97 praxis = gmPraxis.gmCurrentPraxisBranch()
98 pats = praxis.waiting_list_patients
99 zones = {}
100 zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ])
101 self._PRW_zone.update_matcher(items = list(zones))
102
103 #--------------------------------------------------------
104 # edit area mixin API
105 #--------------------------------------------------------
107 if self.patient is None:
108 self._PRW_patient.person = None
109 self._PRW_patient.Enable(True)
110 self._PRW_patient.SetFocus()
111 else:
112 self._PRW_patient.person = self.patient
113 self._PRW_patient.Enable(False)
114 self._TCTRL_comment.SetFocus()
115 self._PRW_patient._display_name()
116
117 self._TCTRL_comment.SetValue('')
118 self._PRW_zone.SetValue('')
119 self._SPCTRL_urgency.SetValue(0)
120 #--------------------------------------------------------
122 self._PRW_patient.person = gmPerson.cPerson(aPK_obj = self.data['pk_identity'])
123 self._PRW_patient.Enable(False)
124 self._PRW_patient._display_name()
125
126 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], ''))
127 self._PRW_zone.SetValue(gmTools.coalesce(self.data['waiting_zone'], ''))
128 self._SPCTRL_urgency.SetValue(self.data['urgency'])
129
130 self._TCTRL_comment.SetFocus()
131 #--------------------------------------------------------
133 validity = True
134
135 self.display_tctrl_as_valid(tctrl = self._PRW_patient, valid = (self._PRW_patient.person is not None))
136 validity = (self._PRW_patient.person is not None)
137
138 if validity is False:
139 self.StatusText = _('Cannot add to waiting list. Missing essential input.')
140
141 return validity
142 #----------------------------------------------------------------
144 # FIXME: filter out dupes ?
145 self._PRW_patient.person.put_on_waiting_list (
146 urgency = self._SPCTRL_urgency.GetValue(),
147 comment = gmTools.none_if(self._TCTRL_comment.GetValue().strip(), ''),
148 zone = gmTools.none_if(self._PRW_zone.GetValue().strip(), '')
149 )
150 # dummy:
151 self.data = {'pk_identity': self._PRW_patient.person.ID, 'comment': None, 'waiting_zone': None, 'urgency': 0}
152 return True
153 #----------------------------------------------------------------
155 gmPraxis.gmCurrentPraxisBranch().update_in_waiting_list (
156 pk = self.data['pk_waiting_list'],
157 urgency = self._SPCTRL_urgency.GetValue(),
158 comment = self._TCTRL_comment.GetValue().strip(),
159 zone = self._PRW_zone.GetValue().strip()
160 )
161 return True
162 #============================================================
163 from Gnumed.wxGladeWidgets import wxgWaitingListPnl
164
166
168
169 wxgWaitingListPnl.wxgWaitingListPnl.__init__(self, *args, **kwargs)
170 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
171
172 self.__current_zone = None
173 self.__id_most_recently_activated_patient = None
174 self.__comment_most_recently_activated_patient = None
175
176 self.__init_ui()
177 self.__register_events()
178 #--------------------------------------------------------
179 # interal helpers
180 #--------------------------------------------------------
182 self._LCTRL_patients.set_columns ([
183 _('Zone'),
184 _('Urgency'),
185 _('Registered'),
186 _('Waiting time'),
187 _('Patient'),
188 _('Born'),
189 _('Comment')
190 ])
191 self._LCTRL_patients.set_column_widths(widths = [wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE_USEHEADER, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE])
192 self._LCTRL_patients.item_tooltip_callback = self._on_get_list_tooltip
193 self._PRW_zone.add_callback_on_selection(callback = self._on_zone_selected)
194 self._PRW_zone.add_callback_on_lose_focus(callback = self._on_zone_selected)
195 #--------------------------------------------------------
197 """
198 This gets called when a patient has been activated, but
199 only when the waiting list is actually in use (that is,
200 the plugin is loaded)
201 """
202 pat = gmPerson.gmCurrentPatient()
203 enc = pat.emr.active_encounter
204 if gmTools.coalesce(enc['reason_for_encounter'], '').strip() != '':
205 return
206 entries = pat.waiting_list_entries
207 if len(entries) == 0:
208 if self.__id_most_recently_activated_patient is None:
209 return
210 if self.__id_most_recently_activated_patient != pat.ID:
211 return
212 rfe = self.__comment_most_recently_activated_patient
213 else:
214 entry = entries[0]
215 if gmTools.coalesce(entry['comment'], '').strip() == '':
216 return
217 rfe = entry['comment'].strip()
218 enc['reason_for_encounter'] = rfe
219 enc.save()
220 self.__id_most_recently_activated_patient = None
221 #--------------------------------------------------------
223
224 dob = gmTools.coalesce (
225 gmTools.coalesce(entry['dob'], '', function4value = ('strftime', '%d %b %Y')),
226 '',
227 ' (%s)'
228 )
229
230 tt = _(
231 '%s patients are waiting.\n'
232 '\n'
233 'Doubleclick to activate (entry will stay in list).'
234 ) % self._LCTRL_patients.GetItemCount()
235
236 tt += _(
237 '\n'
238 '%s\n'
239 'Patient: %s%s\n'
240 '%s'
241 'Urgency: %s\n'
242 'Time: %s\n'
243 '%s'
244 ) % (
245 gmTools.u_box_horiz_single * 50,
246 '%s, %s (%s)' % (entry['lastnames'], entry['firstnames'], entry['l10n_gender']),
247 dob,
248 gmTools.coalesce(entry['waiting_zone'], '', _('Zone: %s\n')),
249 entry['urgency'],
250 gmDateTime.format_interval_medically(entry['waiting_time']),
251 gmTools.coalesce(entry['comment'], '', '\n%s')
252 )
253
254 return tt
255 #--------------------------------------------------------
257 gmDispatcher.connect(signal = 'clin.waiting_list_mod_db', receiver = self._on_waiting_list_modified)
258 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self._on_post_patient_selection)
259 #--------------------------------------------------------
261 self.__id_most_recently_activated_patient = None
262 col, ascending = self._LCTRL_patients.GetSortState() # preserve sorting order
263
264 praxis = gmPraxis.gmCurrentPraxisBranch()
265 pats = praxis.waiting_list_patients
266
267 # set matcher to all zones currently in use
268 zones = {}
269 zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ])
270 self._PRW_zone.update_matcher(items = list(zones))
271
272 # filter patient list by zone and set waiting list
273 self.__current_zone = self._PRW_zone.GetValue().strip()
274 if self.__current_zone == '':
275 pats = [ p for p in pats ]
276 else:
277 pats = [ p for p in pats if p['waiting_zone'] == self.__current_zone ]
278
279 # filter by "active patient only"
280 curr_pat = gmPerson.gmCurrentPatient()
281 if curr_pat.connected:
282 if self._CHBOX_active_patient_only.IsChecked():
283 pats = [ p for p in pats if p['pk_identity'] == curr_pat.ID ]
284
285 old_pks = [ d['pk_waiting_list'] for d in self._LCTRL_patients.get_selected_item_data() ]
286 self._LCTRL_patients.set_string_items (
287 [ [
288 gmTools.coalesce(p['waiting_zone'], ''),
289 p['urgency'],
290 gmDateTime.pydt_strftime(p['registered'], format='%Y %b %d %H:%M'),
291 gmDateTime.format_interval_medically(p['waiting_time']),
292 '%s, %s (%s)' % (p['lastnames'], p['firstnames'], p['l10n_gender']),
293 gmTools.coalesce (
294 gmTools.coalesce (p['dob'], '', function4value = ('strftime', '%d %b %Y')),
295 ''
296 ),
297 gmTools.coalesce(p['comment'], '').split('\n')[0]
298 ] for p in pats ]
299 )
300 self._LCTRL_patients.set_column_widths()
301 self._LCTRL_patients.set_data(pats)
302 new_selections = []
303 new_pks = [ p['pk_waiting_list'] for p in pats ]
304 for old_pk in old_pks:
305 if old_pk in new_pks:
306 new_selections.append(new_pks.index(old_pk))
307 self._LCTRL_patients.selections = new_selections
308 self._LCTRL_patients.Refresh()
309 self._LCTRL_patients.SortListItems(col, ascending) # re-sort
310
311 self._LBL_no_of_patients.SetLabel(_('(%s patients)') % len(pats))
312
313 if len(pats) == 0:
314 self._BTN_activate.Enable(False)
315 self._BTN_activateplus.Enable(False)
316 self._BTN_remove.Enable(False)
317 self._BTN_edit.Enable(False)
318 self._BTN_up.Enable(False)
319 self._BTN_down.Enable(False)
320 else:
321 self._BTN_activate.Enable(True)
322 self._BTN_activateplus.Enable(True)
323 self._BTN_remove.Enable(True)
324 self._BTN_edit.Enable(True)
325 if len(pats) > 1:
326 self._BTN_up.Enable(True)
327 self._BTN_down.Enable(True)
328 #--------------------------------------------------------
329 # event handlers
330 #--------------------------------------------------------
332 self.__id_most_recently_activated_patient = None
333 if self.__current_zone == self._PRW_zone.GetValue().strip():
334 return True
335 wx.CallAfter(self.__refresh_waiting_list)
336 return True
337 #--------------------------------------------------------
341 #--------------------------------------------------------
346 #--------------------------------------------------------
348 self.__id_most_recently_activated_patient = None
349 item = self._LCTRL_patients.get_selected_item_data(only_one=True)
350 if item is None:
351 return
352 try:
353 pat = gmPerson.cPerson(aPK_obj = item['pk_identity'])
354 except gmExceptions.ConstructorError:
355 gmGuiHelpers.gm_show_info (
356 aTitle = _('Waiting list'),
357 aMessage = _('Cannot activate patient.\n\nIt has probably been disabled.')
358 )
359 return
360 curr_pat = gmPerson.gmCurrentPatient()
361 if curr_pat.connected:
362 if curr_pat.ID == item['pk_identity']:
363 edit_waiting_list_entry(parent = self, entry = item)
364 return
365 wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
366 #--------------------------------------------------------
385 #--------------------------------------------------------
406 #--------------------------------------------------------
414 #--------------------------------------------------------
421 #--------------------------------------------------------
460 #--------------------------------------------------------
467 #--------------------------------------------------------
474 #--------------------------------------------------------
477 #--------------------------------------------------------
478 # edit
479 #--------------------------------------------------------
480 # reget-on-paint API
481 #--------------------------------------------------------
485 #================================================================
486 # main
487 #----------------------------------------------------------------
488 if __name__ == '__main__':
489
490 if len(sys.argv) < 2:
491 sys.exit()
492
493 if sys.argv[1] != 'test':
494 sys.exit()
495
496 gmI18N.activate_locale()
497 gmI18N.install_domain()
498
499 #--------------------------------------------------------
500 # def test_generic_codes_prw():
501 # gmPG2.get_connection()
502 # app = wx.PyWidgetTester(size = (500, 40))
503 # pw = cGenericCodesPhraseWheel(app.frame, -1)
504 # #pw.set_context(context = u'zip', val = u'04318')
505 # app.frame.Show(True)
506 # app.MainLoop()
507 # #--------------------------------------------------------
508 # test_generic_codes_prw()
509
510 app = wx.PyWidgetTester(size = (200, 40))
511 app.SetWidget(cWaitingListPnl, -1)
512 app.MainLoop()
513
514 #================================================================
515
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Thu Jul 23 01:55:31 2020 | http://epydoc.sourceforge.net |