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