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