| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed patient overview widgets.
2
3 copyright: authors
4 """
5 #============================================================
6 __author__ = "K.Hilbert"
7 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
8
9 import logging, sys
10
11
12 import wx
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmTools
18 from Gnumed.pycommon import gmDispatcher
19 from Gnumed.pycommon import gmDateTime
20 from Gnumed.pycommon import gmNetworkTools
21
22 from Gnumed.business import gmPerson
23 from Gnumed.business import gmStaff
24 from Gnumed.business import gmDemographicRecord
25 from Gnumed.business import gmEMRStructItems
26 from Gnumed.business import gmFamilyHistory
27 from Gnumed.business import gmVaccination
28 from Gnumed.business import gmDocuments
29 from Gnumed.business import gmProviderInbox
30
31 from Gnumed.wxpython import gmRegetMixin
32 from Gnumed.wxpython import gmDemographicsWidgets
33 from Gnumed.wxpython import gmContactWidgets
34 from Gnumed.wxpython import gmMedicationWidgets
35 from Gnumed.wxpython import gmEditArea
36 from Gnumed.wxpython import gmEMRStructWidgets
37 from Gnumed.wxpython import gmFamilyHistoryWidgets
38 from Gnumed.wxpython import gmVaccWidgets
39 from Gnumed.wxpython import gmDocumentWidgets
40 from Gnumed.wxpython import gmGuiHelpers
41
42
43 _log = logging.getLogger('gm.patient')
44 #============================================================
45 from Gnumed.wxGladeWidgets import wxgPatientOverviewPnl
46
47 -class cPatientOverviewPnl(wxgPatientOverviewPnl.wxgPatientOverviewPnl, gmRegetMixin.cRegetOnPaintMixin):
48
50 wxgPatientOverviewPnl.wxgPatientOverviewPnl.__init__(self, *args, **kwargs)
51 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
52
53 self.__init_ui()
54 self.__register_interests()
55 #--------------------------------------------------------
56 # internal API
57 #--------------------------------------------------------
59 # left
60 self._LCTRL_identity.set_columns(columns = [u''])
61 self._LCTRL_identity.item_tooltip_callback = self._calc_identity_item_tooltip
62 self._LCTRL_identity.activate_callback = self._on_identity_item_activated
63
64 self._LCTRL_contacts.set_columns(columns = [u''])
65 self._LCTRL_contacts.item_tooltip_callback = self._calc_contacts_list_item_tooltip
66 self._LCTRL_contacts.activate_callback = self._on_contacts_item_activated
67
68 self._LCTRL_encounters.set_columns(columns = [u''])
69 self._LCTRL_encounters.item_tooltip_callback = self._calc_encounters_list_item_tooltip
70 self._LCTRL_encounters.activate_callback = self._on_encounter_activated
71
72 # middle
73 self._LCTRL_problems.set_columns(columns = [u''])
74 self._LCTRL_problems.item_tooltip_callback = self._calc_problem_list_item_tooltip
75 self._LCTRL_problems.activate_callback = self._on_problem_activated
76
77 self._LCTRL_meds.set_columns(columns = [u''])
78 self._LCTRL_meds.item_tooltip_callback = self._calc_meds_list_item_tooltip
79 self._LCTRL_meds.activate_callback = self._on_meds_item_activated
80
81 self._LCTRL_history.set_columns(columns = [u''])
82 self._LCTRL_history.item_tooltip_callback = self._calc_history_list_item_tooltip
83 self._LCTRL_history.activate_callback = self._on_history_item_activated
84
85 # right hand side
86 self._LCTRL_inbox.set_columns(columns = [u''])
87 self._LCTRL_inbox.item_tooltip_callback = self._calc_inbox_item_tooltip
88 self._LCTRL_inbox.activate_callback = self._on_inbox_item_activated
89
90 self._LCTRL_results.set_columns(columns = [u''])
91 self._LCTRL_results.item_tooltip_callback = self._calc_results_list_item_tooltip
92 self._LCTRL_results.activate_callback = self._on_result_activated
93
94 self._LCTRL_documents.set_columns(columns = [u''])
95 self._LCTRL_documents.item_tooltip_callback = self._calc_documents_list_item_tooltip
96 self._LCTRL_documents.activate_callback = self._on_document_activated
97 #--------------------------------------------------------
99 self._LCTRL_identity.set_string_items()
100 self._LCTRL_contacts.set_string_items()
101 self._LCTRL_encounters.set_string_items()
102 self._PRW_encounter_range.SetText(value = u'', data = None)
103
104 self._LCTRL_problems.set_string_items()
105 self._LCTRL_meds.set_string_items()
106 self._LCTRL_history.set_string_items()
107
108 self._LCTRL_inbox.set_string_items()
109 self._LCTRL_results.set_string_items()
110 self._LCTRL_documents.set_string_items()
111 #-----------------------------------------------------
112 # event handling
113 #-----------------------------------------------------
114 # remember to call
115 # self._schedule_data_reget()
116 # whenever you learn of data changes from database listener
117 # threads, dispatcher signals etc.
119 # client internal signals
120 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
121 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
122
123 # database change signals
124 gmDispatcher.connect(signal = u'dem.identity_mod_db', receiver = self._on_post_patient_selection)
125 gmDispatcher.connect(signal = u'dem.names_mod_db', receiver = self._on_post_patient_selection)
126 gmDispatcher.connect(signal = u'dem.comm_channel_mod_db', receiver = self._on_post_patient_selection)
127 gmDispatcher.connect(signal = u'dem.job_mod_db', receiver = self._on_post_patient_selection)
128 # no signal for external IDs yet
129 # no signal for address yet
130 #gmDispatcher.connect(signal = u'current_encounter_modified', receiver = self._on_current_encounter_modified)
131 #gmDispatcher.connect(signal = u'current_encounter_switched', receiver = self._on_current_encounter_switched)
132
133 gmDispatcher.connect(signal = u'clin.episode_mod_db', receiver = self._on_episode_issue_mod_db)
134 gmDispatcher.connect(signal = u'clin.health_issue_mod_db', receiver = self._on_episode_issue_mod_db)
135
136 gmDispatcher.connect(signal = u'clin.substance_intake_mod_db', receiver = self._on_post_patient_selection)
137
138 gmDispatcher.connect(signal = u'clin.hospital_stay_mod_db', receiver = self._on_post_patient_selection)
139 gmDispatcher.connect(signal = u'clin.family_history_mod_db', receiver = self._on_post_patient_selection)
140 gmDispatcher.connect(signal = u'clin.procedure_mod_db', receiver = self._on_post_patient_selection)
141 gmDispatcher.connect(signal = u'clin.vaccination_mod_db', receiver = self._on_post_patient_selection)
142 #gmDispatcher.connect(signal = u'gm_table_mod', receiver = self._on_post_patient_selection)
143
144 gmDispatcher.connect(signal = u'dem.message_inbox_mod_db', receiver = self._on_post_patient_selection)
145 gmDispatcher.connect(signal = u'clin.test_result_mod_db', receiver = self._on_post_patient_selection)
146 gmDispatcher.connect(signal = u'clin.reviewed_test_results_mod_db', receiver = self._on_post_patient_selection)
147 gmDispatcher.connect(signal = u'blobs.doc_med_mod_db', receiver = self._on_post_patient_selection)
148
149 # synchronous signals
150 # self.__pat.register_pre_selection_callback(callback = self._pre_selection_callback)
151 # gmDispatcher.send(signal = u'register_pre_exit_callback', callback = self._pre_exit_callback)
152
153 self._PRW_encounter_range.add_callback_on_selection(callback = self._on_encounter_range_selected)
154 #--------------------------------------------------------
157 #--------------------------------------------------------
159 # only empty out here, do NOT access the patient
160 # or else we will access the old patient while it
161 # may not be valid anymore ...
162 wx.CallAfter(self.__reset_ui_content)
163 #--------------------------------------------------------
166 #--------------------------------------------------------
169 #-----------------------------------------------------
170 # reget-on-paint mixin API
171 #-----------------------------------------------------
173 pat = gmPerson.gmCurrentPatient()
174 if not pat.connected:
175 self.__reset_ui_content()
176 return True
177
178 self.__refresh_identity(patient = pat)
179 self.__refresh_contacts(patient = pat)
180 self.__refresh_encounters(patient = pat)
181
182 self.__refresh_problems(patient = pat)
183 self.__refresh_meds(patient = pat)
184 self.__refresh_history(patient = pat)
185
186 self.__refresh_inbox(patient = pat)
187 self.__refresh_results(patient = pat)
188 self.__refresh_documents(patient = pat)
189
190 return True
191 #-----------------------------------------------------
192 # internal helpers
193 #-----------------------------------------------------
195 list_items = []
196 list_data = []
197
198 emr = patient.get_emr()
199 most_recent = emr.get_most_recent_results(no_of_results = 1)
200 if most_recent is None:
201 self._LCTRL_results.set_string_items(items = [])
202 self._LCTRL_results.set_data(data = [])
203 return
204
205 list_items.append(_('Latest: %s ago (%s %s %s %s%s)') % (
206 gmDateTime.format_interval_medically(gmDateTime.pydt_now_here() - most_recent['clin_when']),
207 most_recent['unified_abbrev'],
208 most_recent['unified_val'],
209 most_recent['val_unit'],
210 gmTools.coalesce(most_recent['abnormality_indicator'], u'', u' %s'),
211 gmTools.bool2subst(most_recent['reviewed'], u'', u' %s' % gmTools.u_writing_hand)
212 ))
213 list_data.append(most_recent)
214 most_recent_needs_red = False
215 #if most_recent['is_technically_abnormal'] is True:
216 if most_recent.is_considered_abnormal is True:
217 if most_recent['is_clinically_relevant']:
218 most_recent_needs_red = True
219 # else:
220 # if most_recent['abnormality_indicator'] not in [None, u'']:
221 # most_recent_needs_red = True
222
223 unsigned = emr.get_unsigned_results(order_by = u"(trim(coalesce(abnormality_indicator), '') <> '') DESC NULLS LAST, unified_abbrev")
224 no_of_reds = 0
225 for result in unsigned:
226 if result['pk_test_result'] == most_recent['pk_test_result']:
227 continue
228 if result['abnormality_indicator'] is not None:
229 if result['abnormality_indicator'].strip() != u'':
230 no_of_reds += 1
231 list_items.append(_('%s %s %s %s (%s ago, %s)') % (
232 result['unified_abbrev'],
233 result['unified_val'],
234 result['val_unit'],
235 gmTools.coalesce(result['abnormality_indicator'], u'', u' %s'),
236 gmDateTime.format_interval_medically(gmDateTime.pydt_now_here() - result['clin_when']),
237 gmTools.u_writing_hand
238 ))
239 list_data.append(result)
240
241 self._LCTRL_results.set_string_items(items = list_items)
242 self._LCTRL_results.set_data(data = list_data)
243
244 if most_recent_needs_red:
245 self._LCTRL_results.SetItemTextColour(0, wx.NamedColour('RED'))
246 if no_of_reds > 0:
247 for idx in range(1, no_of_reds + 1):
248 self._LCTRL_results.SetItemTextColour(idx, wx.NamedColour('RED'))
249 #-----------------------------------------------------
252 #-----------------------------------------------------
254 # data = self._LCTRL_inbox.get_selected_item_data(only_one = True)
255 #
256 # if data is not None:
257 # # <ctrl> down ?
258 # if wx.GetKeyState(wx.WXK_CONTROL):
259 # if isinstance(data, gmProviderInbox.cInboxMessage):
260 # xxxxxxxxx
261 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmMeasurementsGridPlugin')
262 return
263 #-----------------------------------------------------
264 #-----------------------------------------------------
266 list_items = []
267 list_data = []
268
269 overdue_messages = patient.overdue_messages
270 no_of_overdues = len(overdue_messages)
271 for msg in overdue_messages:
272 list_items.append(_('overdue %s: %s') % (
273 gmDateTime.format_interval_medically(msg['interval_due']),
274 gmTools.coalesce(msg['comment'], u'?')
275 ))
276 list_data.append(msg)
277
278 for msg in patient.get_messages(order_by = u'due_date NULLS LAST, importance DESC, received_when DESC'):
279 # already displayed above ?
280 if msg['is_overdue']:
281 continue
282 # not relevant anymore ?
283 if msg['is_expired']:
284 continue
285 if msg['due_date'] is None:
286 label = u'%s%s' % (
287 msg['l10n_type'],
288 gmTools.coalesce(msg['comment'], u'', u': %s')
289 )
290 else:
291 label = _('due in %s%s') % (
292 gmDateTime.format_interval_medically(msg['interval_due']),
293 gmTools.coalesce(msg['comment'], u'', u': %s')
294 )
295
296 list_items.append(label)
297 list_data.append(msg)
298
299 for hint in patient.dynamic_hints:
300 list_items.append(hint['title'])
301 list_data.append(hint)
302
303 self._LCTRL_inbox.set_string_items(items = list_items)
304 self._LCTRL_inbox.set_data(data = list_data)
305
306 if no_of_overdues > 0:
307 for idx in range(no_of_overdues):
308 self._LCTRL_inbox.SetItemTextColour(idx, wx.NamedColour('RED'))
309 #-----------------------------------------------------
311 if isinstance(data, gmProviderInbox.cInboxMessage):
312 return data.format()
313
314 if isinstance(data, gmProviderInbox.cDynamicHint):
315 return u'%s\n\n%s\n\n%s %s' % (
316 data['title'],
317 gmTools.wrap(data['hint'], width = 50),
318 gmTools.wrap(gmTools.coalesce(data['url'], u'', u'%s\n\n'), width = 50),
319 data['source']
320 )
321
322 return None
323 #-----------------------------------------------------
325
326 data = self._LCTRL_inbox.get_selected_item_data(only_one = True)
327
328 if isinstance(data, gmProviderInbox.cDynamicHint):
329 if data['url'] is not None:
330 gmNetworkTools.open_url_in_browser(data['url'])
331 return
332
333 # <ctrl> down ?
334 if not wx.GetKeyState(wx.WXK_CONTROL):
335 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin')
336 return
337
338 if data is None:
339 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin')
340 return
341
342 if not isinstance(data, gmProviderInbox.cInboxMessage):
343 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmProviderInboxPlugin')
344 return
345
346 delete_it = gmGuiHelpers.gm_show_question (
347 question = _('Do you really want to\ndelete this inbox message ?'),
348 title = _('Deleting inbox message')
349 )
350 if not delete_it:
351 return
352
353 gmProviderInbox.delete_inbox_message(inbox_message = data['pk_inbox_message'])
354 return
355 #-----------------------------------------------------
356 #-----------------------------------------------------
358 doc_folder = patient.get_document_folder()
359
360 list_items = []
361 list_data = []
362
363 docs = doc_folder.get_unsigned_documents()
364 no_of_unsigned = len(docs)
365 for doc in docs:
366 list_items.append(u'%s %s (%s)' % (
367 gmDateTime.pydt_strftime(doc['clin_when'], format = '%m/%Y', accuracy = gmDateTime.acc_months),
368 doc['l10n_type'],
369 gmTools.u_writing_hand
370 ))
371 list_data.append(doc)
372
373 docs = doc_folder.get_documents(order_by = u'ORDER BY clin_when DESC', exclude_unsigned = True)
374 for doc in docs[:5]:
375 list_items.append(u'%s %s' % (
376 gmDateTime.pydt_strftime(doc['clin_when'], format = '%m/%Y', accuracy = gmDateTime.acc_months),
377 doc['l10n_type']
378 ))
379 list_data.append(doc)
380 if len(docs) > 5:
381 list_items.append(_('%s %s more not shown %s') % (
382 gmTools.u_ellipsis,
383 len(docs) - 5,
384 gmTools.u_ellipsis
385 ))
386 list_data.append(u'')
387
388 self._LCTRL_documents.set_string_items(items = list_items)
389 self._LCTRL_documents.set_data(data = list_data)
390
391 if no_of_unsigned > 0:
392 for idx in range(no_of_unsigned):
393 self._LCTRL_documents.SetItemTextColour(idx, wx.NamedColour('RED'))
394 #-----------------------------------------------------
396 emr = gmPerson.gmCurrentPatient().get_emr()
397
398 if isinstance(data, gmDocuments.cDocument):
399 return data.format()
400
401 return None
402 #-----------------------------------------------------
404 data = self._LCTRL_documents.get_selected_item_data(only_one = True)
405
406 if data is not None:
407 # <ctrl> down ?
408 if wx.GetKeyState(wx.WXK_CONTROL):
409 if isinstance(data, gmDocuments.cDocument):
410 if len(data.parts) > 0:
411 gmDocumentWidgets.display_document_part(parent = self, part = data.parts[0])
412 else:
413 gmDocumentWidgets.review_document(parent = self, document = data)
414 return
415
416 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmShowMedDocs')
417 return
418 #-----------------------------------------------------
419 #-----------------------------------------------------
421
422 cover_period = self._PRW_encounter_range.GetData()
423 if cover_period is None:
424 if self._PRW_encounter_range.GetValue().strip() != u'':
425 return
426
427 emr = patient.get_emr()
428
429 list_items = []
430 list_data = []
431
432 is_waiting = False
433 wlist = patient.get_waiting_list_entry()
434 if len(wlist) > 0:
435 is_waiting = True
436 list_items.append(_('Currently %s entries in waiting list') % len(wlist))
437 tt = []
438 for w in wlist:
439 tt.append(u'%s %s%s%s' % (
440 gmTools.u_triangular_bullet,
441 gmDateTime.format_interval_medically(w['waiting_time']),
442 gmTools.coalesce(w['waiting_zone'], u'', u' in "%s"'),
443 gmTools.coalesce(w['comment'], u'', u': %s')
444 ))
445 if len(tt) > 0:
446 tt = u'\n'.join(tt)
447 else:
448 tt = None
449 list_data.append({'wlist': tt})
450
451 first = emr.get_first_encounter()
452 if first is not None:
453 list_items.append (
454 _('first: %s, %s') % (
455 gmDateTime.pydt_strftime (
456 first['started'],
457 format = '%Y %b %d',
458 accuracy = gmDateTime.acc_days
459 ),
460 first['l10n_type']
461 )
462 )
463 list_data.append(first)
464
465 last = emr.get_last_but_one_encounter()
466 if last is not None:
467 list_items.append (
468 _('last: %s, %s') % (
469 gmDateTime.pydt_strftime (
470 last['started'],
471 format = '%Y %b %d',
472 accuracy = gmDateTime.acc_days
473 ),
474 last['l10n_type']
475 )
476 )
477 list_data.append(last)
478
479 if cover_period is not None:
480 item = _('Last %s:') % self._PRW_encounter_range.GetValue().strip()
481 list_items.append(item)
482 list_data.append(_('Statistics cover period'))
483
484 encs = emr.get_encounter_stats_by_type(cover_period = cover_period)
485 for enc in encs:
486 item = u' %s x %s' % (enc['frequency'], enc['l10n_type'])
487 list_items.append(item)
488 list_data.append(item)
489
490 stays = emr.get_hospital_stay_stats_by_hospital(cover_period = cover_period)
491 for stay in stays:
492 item = u' %s x %s' % (
493 stay['frequency'],
494 stay['hospital']
495 )
496 list_items.append(item)
497 list_data.append({'stay': item})
498
499 self._LCTRL_encounters.set_string_items(items = list_items)
500 self._LCTRL_encounters.set_data(data = list_data)
501 if is_waiting:
502 self._LCTRL_encounters.SetItemTextColour(0, wx.NamedColour('RED'))
503 #-----------------------------------------------------
505 emr = gmPerson.gmCurrentPatient().get_emr()
506
507 if isinstance(data, gmEMRStructItems.cEncounter):
508 return data.format (
509 with_vaccinations = False,
510 with_tests = False,
511 with_docs = False,
512 with_co_encountlet_hints = True,
513 with_rfe_aoe = True
514 )
515
516 if type(data) == type({}):
517 key, val = data.items()[0]
518 if key == 'wlist':
519 return val
520 if key == 'stay':
521 return None
522
523 return data
524 #-----------------------------------------------------
526 data = self._LCTRL_encounters.get_selected_item_data(only_one = True)
527 if data is not None:
528 # <ctrl> down ?
529 if wx.GetKeyState(wx.WXK_CONTROL):
530 if isinstance(data, gmEMRStructItems.cEncounter):
531 gmEMRStructWidgets.edit_encounter(parent = self, encounter = data)
532 return
533
534 if type(data) == type({}):
535 key, val = data.items()[0]
536 if key == 'wlist':
537 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmWaitingListPlugin')
538 return
539 if key == 'stay':
540 wx.CallAfter(gmEMRStructWidgets.manage_hospital_stays, parent = self)
541 return
542
543 wx.CallAfter(gmEMRStructWidgets.manage_encounters, parent = self, ignore_OK_button = False)
544 #-----------------------------------------------------
545 #-----------------------------------------------------
547 emr = patient.get_emr()
548
549 list_items = []
550 list_data = []
551
552 issues = [
553 i for i in emr.get_health_issues()
554 if ((i['clinically_relevant'] is False) or (i['is_active'] is False))
555 ]
556 for issue in issues:
557 last_encounter = emr.get_last_encounter(issue_id = issue['pk_health_issue'])
558 if last_encounter is None:
559 last = issue['modified_when'].strftime('%m/%Y')
560 else:
561 last = last_encounter['last_affirmed'].strftime('%m/%Y')
562 list_items.append(u'%s %s' % (last, issue['description']))
563 list_data.append(issue)
564 del issues
565
566 fhxs = emr.get_family_history()
567 for fhx in fhxs:
568 list_items.append(u'%s: %s%s' % (
569 fhx['l10n_relation'],
570 fhx['condition'],
571 gmTools.coalesce(fhx['age_noted'], u'', u' (@ %s)')
572 ))
573 list_data.append(fhx)
574 del fhxs
575
576 stays = emr.get_hospital_stays()
577 for stay in stays:
578 if stay['discharge'] is not None:
579 discharge = u''
580 else:
581 discharge = gmTools.u_ellipsis
582 list_items.append(u'%s%s %s: %s' % (
583 gmDateTime.pydt_strftime(stay['admission'], format = '%Y %b %d'),
584 discharge,
585 stay['hospital'],
586 stay['episode']
587 ))
588 list_data.append(stay)
589 del stays
590
591 procs = emr.get_performed_procedures()
592 for proc in procs:
593 list_items.append(u'%s%s %s' % (
594 gmDateTime.pydt_strftime(proc['clin_when'], format = '%Y %b %d'),
595 gmTools.bool2subst(proc['is_ongoing'], gmTools.u_ellipsis, u'', u''),
596 proc['performed_procedure']
597 ))
598 list_data.append(proc)
599 del procs
600
601 vaccs = emr.get_latest_vaccinations()
602 for ind, tmp in vaccs.items():
603 tmp, vacc = tmp
604 list_items.append(_('%s Vacc: %s') % (
605 gmDateTime.pydt_strftime(vacc['date_given'], format = '%Y %b %d'),
606 ind
607 ))
608 list_data.append(vacc)
609 del vaccs
610
611 self._LCTRL_history.set_string_items(items = list_items)
612 self._LCTRL_history.set_data(data = list_data)
613 #-----------------------------------------------------
615
616 if isinstance(data, gmEMRStructItems.cHealthIssue):
617 return data.format (
618 patient = gmPerson.gmCurrentPatient(),
619 with_medications = False,
620 with_hospital_stays = False,
621 with_procedures = False,
622 with_family_history = False,
623 with_documents = False,
624 with_tests = False,
625 with_vaccinations = False
626 ).strip(u'\n')
627
628 if isinstance(data, gmFamilyHistory.cFamilyHistory):
629 return data.format(include_episode = True, include_comment = True)
630
631 if isinstance(data, gmEMRStructItems.cHospitalStay):
632 return data.format()
633
634 if isinstance(data, gmEMRStructItems.cPerformedProcedure):
635 return data.format(include_episode = True)
636
637 if isinstance(data, gmVaccination.cVaccination):
638 return u'\n'.join(data.format (
639 with_indications = True,
640 with_comment = True,
641 with_reaction = True,
642 date_format = '%Y %b %d'
643 ))
644
645 return None
646 #-----------------------------------------------------
648 data = self._LCTRL_history.get_selected_item_data(only_one = True)
649 if data is None:
650 return
651
652 # <ctrl> down ?
653 if wx.GetKeyState(wx.WXK_CONTROL):
654 if isinstance(data, gmEMRStructItems.cHealthIssue):
655 gmEMRStructWidgets.edit_health_issue(parent = self, issue = data)
656 return
657 if isinstance(data, gmFamilyHistory.cFamilyHistory):
658 FamilyHistoryWidgets.edit_family_history(parent = self, family_history = data)
659 return
660 if isinstance(data, gmEMRStructItems.cHospitalStay):
661 gmEMRStructWidgets.edit_hospital_stay(parent = self, hospital_stay = data)
662 return
663 if isinstance(data, gmEMRStructItems.cPerformedProcedure):
664 gmEMRStructWidgets.edit_procedure(parent = self, procedure = data)
665 return
666 if isinstance(data, gmVaccination.cVaccination):
667 gmVaccWidgets.edit_vaccination(parent = self, vaccination = data, single_entry = True)
668 return
669 return
670
671 if isinstance(data, gmEMRStructItems.cHealthIssue):
672 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmEMRBrowserPlugin')
673 return
674 if isinstance(data, gmFamilyHistory.cFamilyHistory):
675 FamilyHistoryWidgets.manage_family_history(parent = self)
676 return
677 if isinstance(data, gmEMRStructItems.cHospitalStay):
678 gmEMRStructWidgets.manage_hospital_stays(parent = self)
679 return
680 if isinstance(data, gmEMRStructItems.cPerformedProcedure):
681 gmEMRStructWidgets.manage_performed_procedures(parent = self)
682 return
683 if isinstance(data, gmVaccination.cVaccination):
684 gmVaccWidgets.manage_vaccinations(parent = self)
685 return
686
687 return
688 #-----------------------------------------------------
689 #-----------------------------------------------------
691 # list by brand or substance:
692 emr = patient.get_emr()
693 intakes = emr.get_current_substance_intakes(include_inactive = False, include_unapproved = True, order_by = u'substance')
694
695 list_items = []
696 multi_brands_already_seen = []
697 data_items = []
698 for intake in intakes:
699 brand = intake.containing_drug
700 if brand is None or len(brand['pk_components']) == 1:
701 list_items.append(_('%s %s %s%s') % (
702 intake['substance'],
703 intake['amount'],
704 intake['unit'],
705 gmTools.coalesce (
706 intake['schedule'],
707 u'',
708 u': %s'
709 )
710 ))
711 data_items.append(intake)
712 else:
713 if intake['brand'] in multi_brands_already_seen:
714 continue
715 multi_brands_already_seen.append(intake['brand'])
716 list_items.append(_('%s %s%s') % (
717 intake['brand'],
718 brand['preparation'],
719 gmTools.coalesce (
720 intake['schedule'],
721 u'',
722 u': %s'
723 )
724 ))
725 data_items.append(intake)
726 self._LCTRL_meds.set_string_items(items = list_items)
727 self._LCTRL_meds.set_data(data = data_items)
728 #-----------------------------------------------------
730 emr = gmPerson.gmCurrentPatient().get_emr()
731 atcs = []
732 if data['atc_substance'] is not None:
733 atcs.append(data['atc_substance'])
734 # if data['atc_brand'] is not None:
735 # atcs.append(data['atc_brand'])
736 # allg = emr.is_allergic_to(atcs = tuple(atcs), inns = (data['substance'],), brand = data['brand'])
737 allg = emr.is_allergic_to(atcs = tuple(atcs), inns = (data['substance'],))
738 if allg is False:
739 allg = None
740 return data.format(one_line = False, allergy = allg, show_all_brand_components = True)
741 #-----------------------------------------------------
743 data = self._LCTRL_meds.get_selected_item_data(only_one = True)
744 if data is not None:
745 # <ctrl> down ?
746 if wx.GetKeyState(wx.WXK_CONTROL):
747 wx.CallAfter(gmMedicationWidgets.edit_intake_of_substance, parent = self, substance = data)
748 return
749
750 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmCurrentSubstancesPlugin')
751 #-----------------------------------------------------
752 #-----------------------------------------------------
754 emr = patient.get_emr()
755
756 list_items = []
757 list_data = []
758 is_in_hospital = False
759
760 stays = emr.get_hospital_stays(ongoing_only = True)
761 if len(stays) > 0:
762 list_items.append(_('** Currently hospitalized: %s **') % stays[0]['hospital'])
763 list_data.append(stays[0])
764 is_in_hospital = True
765
766 adrs = patient.get_addresses()
767 for adr in adrs:
768 list_items.append(adr.format(single_line = True, verbose = False, show_type = True))
769 list_data.append(adr)
770
771 comms = patient.get_comm_channels()
772 for comm in comms:
773 list_items.append(u'%s: %s%s' % (
774 comm['l10n_comm_type'],
775 comm['url'],
776 gmTools.coalesce(comm['comment'], u'', u' (%s)')
777 ))
778 list_data.append(comm)
779
780 ident = patient.emergency_contact_in_database
781 if ident is not None:
782 list_items.append(_('emergency: %s') % ident['description_gender'])
783 list_data.append(ident)
784
785 if patient['emergency_contact'] is not None:
786 list_items.append(_('emergency: %s') % patient['emergency_contact'].split(u'\n')[0])
787 list_data.append(patient['emergency_contact'])
788
789 provider = patient.primary_provider
790 if provider is not None:
791 list_items.append(_('in-praxis: %s') % provider.identity['description_gender'])
792 list_data.append(provider)
793
794 self._LCTRL_contacts.set_string_items(items = list_items)
795 self._LCTRL_contacts.set_data(data = list_data)
796 if is_in_hospital:
797 self._LCTRL_contacts.SetItemTextColour(0, wx.NamedColour('RED'))
798 #-----------------------------------------------------
800
801 if isinstance(data, gmEMRStructItems.cHospitalStay):
802 return data.format()
803
804 if isinstance(data, gmDemographicRecord.cPatientAddress):
805 return u'\n'.join(data.format())
806
807 if isinstance(data, gmDemographicRecord.cCommChannel):
808 parts = []
809 if data['is_confidential']:
810 parts.append(_('*** CONFIDENTIAL ***'))
811 if data['comment'] is not None:
812 parts.append(data['comment'])
813 return u'\n'.join(parts)
814
815 if isinstance(data, gmPerson.cIdentity):
816 return u'%s\n\n%s' % (
817 data['description_gender'],
818 u'\n'.join([
819 u'%s: %s%s' % (
820 c['l10n_comm_type'],
821 c['url'],
822 gmTools.bool2subst(c['is_confidential'], _(' (confidential !)'), u'', u'')
823 )
824 for c in data.get_comm_channels()
825 ])
826 )
827
828 if isinstance(data, basestring):
829 return data
830
831 if isinstance(data, gmStaff.cStaff):
832 ident = data.identity
833 return u'%s: %s\n\n%s%s' % (
834 data['short_alias'],
835 ident['description_gender'],
836 u'\n'.join([
837 u'%s: %s%s' % (
838 c['l10n_comm_type'],
839 c['url'],
840 gmTools.bool2subst(c['is_confidential'], _(' (confidential !)'), u'', u'')
841 )
842 for c in ident.get_comm_channels()
843 ]),
844 gmTools.coalesce(data['comment'], u'', u'\n\n%s')
845 )
846
847 return None
848 #-----------------------------------------------------
850 data = self._LCTRL_contacts.get_selected_item_data(only_one = True)
851 if data is not None:
852 # <ctrl> down ?
853 if wx.GetKeyState(wx.WXK_CONTROL):
854 if isinstance(data, gmEMRStructItems.cHospitalStay):
855 gmEMRStructWidgets.edit_hospital_stay(parent = self, hospital_stay = data)
856 return
857 if isinstance(data, gmDemographicRecord.cPatientAddress):
858 pass
859 if isinstance(data, gmDemographicRecord.cCommChannel):
860 gmContactWidgets.edit_comm_channel(parent = self, comm_channel = data, channel_owner = gmPerson.gmCurrentPatient())
861 return
862 if isinstance(data, gmPerson.cIdentity):
863 pass
864 if isinstance(data, gmStaff.cStaff):
865 pass
866
867 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin')
868 #-----------------------------------------------------
869 #-----------------------------------------------------
871 emr = patient.get_emr()
872
873 problems = [
874 p for p in emr.get_problems(include_closed_episodes = False, include_irrelevant_issues = False)
875 if p['problem_active']
876 ]
877
878 list_items = []
879 for problem in problems:
880 if problem['type'] == 'issue':
881 issue = emr.problem2issue(problem)
882 last_encounter = emr.get_last_encounter(issue_id = issue['pk_health_issue'])
883 if last_encounter is None:
884 last = issue['modified_when'].strftime('%m/%Y')
885 else:
886 last = last_encounter['last_affirmed'].strftime('%m/%Y')
887 list_items.append(u'%s: %s' % (problem['problem'], last))
888
889 elif problem['type'] == 'episode':
890 epi = emr.problem2episode(problem)
891 last_encounter = emr.get_last_encounter(episode_id = epi['pk_episode'])
892 if last_encounter is None:
893 last = epi['episode_modified_when'].strftime('%m/%Y')
894 else:
895 last = last_encounter['last_affirmed'].strftime('%m/%Y')
896 list_items.append(u'%s: %s' % (problem['problem'], last))
897
898 self._LCTRL_problems.set_string_items(items = list_items)
899 self._LCTRL_problems.set_data(data = problems)
900 #-----------------------------------------------------
902 emr = gmPerson.gmCurrentPatient().get_emr()
903
904 if data['type'] == 'issue':
905 issue = emr.problem2issue(data)
906 tt = issue.format (
907 patient = gmPerson.gmCurrentPatient(),
908 with_medications = False,
909 with_hospital_stays = False,
910 with_procedures = False,
911 with_family_history = False,
912 with_documents = False,
913 with_tests = False,
914 with_vaccinations = False
915 ).strip(u'\n')
916 return tt
917
918 if data['type'] == 'episode':
919 epi = emr.problem2episode(data)
920 tt = epi.format (
921 patient = gmPerson.gmCurrentPatient(),
922 with_encounters = False,
923 with_hospital_stays = False,
924 with_procedures = False,
925 with_family_history = False,
926 with_documents = False,
927 with_tests = False,
928 with_vaccinations = False,
929 with_health_issue = True
930 ).strip(u'\n')
931 return tt
932
933 return None
934 #-----------------------------------------------------
936 data = self._LCTRL_problems.get_selected_item_data(only_one = True)
937 if data is not None:
938 # <ctrl> down ?
939 if wx.GetKeyState(wx.WXK_CONTROL):
940 emr = gmPerson.gmCurrentPatient().get_emr()
941 if data['type'] == 'issue':
942 gmEMRStructWidgets.edit_health_issue(parent = self, issue = emr.problem2issue(data))
943 return
944 if data['type'] == 'episode':
945 gmEMRStructWidgets.edit_episode(parent = self, episode = emr.problem2episode(data))
946 return
947
948 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmEMRBrowserPlugin')
949 #-----------------------------------------------------
950 #-----------------------------------------------------
952 # names (.comment -> tooltip)
953 names = patient.get_names(exclude_active = True)
954 items = [
955 _('aka: %(last)s, %(first)s%(nick)s') % {
956 'last': n['lastnames'],
957 'first': n['firstnames'],
958 'nick': gmTools.coalesce(n['preferred'], u'', u" '%s'")
959 } for n in names
960 ]
961 data = names
962
963 # IDs (.issuer & .comment -> tooltip)
964 ids = patient.external_ids
965 for i in ids:
966 items.append(u'%s: %s' % (i['name'], i['value']))
967 data.append({'id': i})
968
969 # occupation
970 jobs = patient.get_occupations()
971 for j in jobs:
972 items.append(_('job: %s (%s)') % (
973 j['l10n_occupation'],
974 j['modified_when'].strftime('%m/%Y')
975 ))
976 data.append({'job': j})
977
978 self._LCTRL_identity.set_string_items(items = items)
979 self._LCTRL_identity.set_data(data = data)
980 #-----------------------------------------------------
982 if isinstance(data, gmPerson.cPersonName):
983 return data['comment']
984 if isinstance(data, type({})):
985 key = data.keys()[0]
986 val = data[key]
987 if key == 'id':
988 return _('issued by: %s%s') % (
989 val['issuer'],
990 gmTools.coalesce(val['comment'], u'', u'\n\n%s')
991 )
992 if key == 'job':
993 tt = _('Last modified: %s') % val['modified_when'].strftime('%m/%Y')
994 if val['activities'] is None:
995 return tt
996 return tt + (u'\n\n' + _('Activities:\n\n%s') % val['activities'])
997
998 return None
999 #-----------------------------------------------------
1001 data = self._LCTRL_identity.get_selected_item_data(only_one = True)
1002 if data is not None:
1003 # <ctrl> down ?
1004 if wx.GetKeyState(wx.WXK_CONTROL):
1005 if isinstance(data, gmPerson.cPersonName):
1006 ea = gmDemographicsWidgets.cPersonNameEAPnl(self, -1, name = data)
1007 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True)
1008 dlg.SetTitle(_('Cloning name'))
1009 dlg.ShowModal()
1010 return
1011 if isinstance(data, type({})):
1012 key = data.keys()[0]
1013 val = data[key]
1014 if key == 'id':
1015 ea = gmDemographicsWidgets.cExternalIDEditAreaPnl(self, -1, external_id = val)
1016 ea.identity = gmPerson.gmCurrentPatient()
1017 dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True)
1018 dlg.SetTitle(_('Editing external ID'))
1019 dlg.ShowModal()
1020 return
1021 if key == 'job':
1022 gmDemographicsWidgets.edit_occupation()
1023 return
1024
1025 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin')
1026 #============================================================
1027 # main
1028 #------------------------------------------------------------
1029 if __name__ == "__main__":
1030
1031 if len(sys.argv) < 2:
1032 sys.exit()
1033
1034 if sys.argv[1] != u'test':
1035 sys.exit()
1036
1037 # from Gnumed.pycommon import gmPG2
1038 # from Gnumed.pycommon import gmI18N
1039 # gmI18N.activate_locale()
1040 # gmI18N.install_domain()
1041
1042 #--------------------------------------------------------
1043 #test_org_unit_prw()
1044
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Aug 3 03:56:40 2013 | http://epydoc.sourceforge.net |