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