1 """GNUmed narrative workflows."""
2
3 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
4 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
5
6 import sys
7 import logging
8 import os.path
9 import time
10
11
12 import wx
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17
18 from Gnumed.pycommon import gmI18N
19
20 if __name__ == '__main__':
21 gmI18N.activate_locale()
22 gmI18N.install_domain()
23
24 from Gnumed.pycommon import gmDispatcher
25 from Gnumed.pycommon import gmTools
26 from Gnumed.pycommon import gmDateTime
27
28 from Gnumed.business import gmPerson
29 from Gnumed.business import gmStaff
30 from Gnumed.business import gmEMRStructItems
31 from Gnumed.business import gmClinNarrative
32 from Gnumed.business import gmSoapDefs
33 from Gnumed.business import gmProviderInbox
34
35 from Gnumed.wxpython import gmListWidgets
36 from Gnumed.wxpython import gmEMRStructWidgets
37 from Gnumed.wxpython import gmEncounterWidgets
38 from Gnumed.wxpython import gmGuiHelpers
39 from Gnumed.wxpython import gmNarrativeWidgets
40 from Gnumed.wxpython.gmPatSearchWidgets import set_active_patient
41
42 from Gnumed.exporters import gmPatientExporter
43
44
45 _log = logging.getLogger('gm.ui')
46
47
48
49
51 assert isinstance(narrative, gmClinNarrative.cNarrative), '<narrative> must be of type <cNarrative>'
52
53 title = _('Editing progress note')
54 if narrative['modified_by_raw'] == gmStaff.gmCurrentProvider()['db_user']:
55 msg = _('Your original progress note:')
56 else:
57 msg = _('Original progress note by %s [%s]\n(will be notified of changes):') % (
58 narrative['modified_by'],
59 narrative['modified_by_raw']
60 )
61 if parent is None:
62 parent = wx.GetApp().GetTopWindow()
63 dlg = gmGuiHelpers.cMultilineTextEntryDlg (
64 parent,
65 -1,
66 title = title,
67 msg = msg,
68 data = narrative.format(left_margin = ' ', fancy = True),
69 text = narrative['narrative'].strip()
70 )
71 decision = dlg.ShowModal()
72 val = dlg.value.strip()
73 dlg.DestroyLater()
74 if decision != wx.ID_SAVE:
75 return False
76
77 if val == '':
78 return False
79
80 if val == narrative['narrative'].strip():
81 return False
82
83 if narrative['modified_by_raw'] == gmStaff.gmCurrentProvider()['db_user']:
84 narrative['narrative'] = val
85 narrative.save_payload()
86 return True
87
88 q = _(
89 'Original progress note written by someone else:\n'
90 '\n'
91 ' %s (%s)\n'
92 '\n'
93 'Upon saving changes that person will be notified.\n'
94 '\n'
95 'Consider saving as a new progress note instead.'
96 ) % (
97 narrative['modified_by_raw'],
98 narrative['modified_by']
99 )
100 buttons = [
101 {'label': _('Save changes'), 'default': True},
102 {'label': _('Save new note')},
103 {'label': _('Discard')}
104 ]
105 dlg = gmGuiHelpers.c3ButtonQuestionDlg(parent = parent, caption = title, question = q, button_defs = buttons)
106 decision = dlg.ShowModal()
107 dlg.DestroyLater()
108 if decision not in [wx.ID_YES, wx.ID_NO]:
109 return False
110
111 if decision == wx.ID_NO:
112
113 gmClinNarrative.create_narrative_item (
114 narrative = val,
115 soap_cat = narrative['soap_cat'],
116 episode_id = narrative['pk_episode'],
117 encounter_id = narrative['pk_encounter']
118 )
119 return True
120
121
122 msg = gmProviderInbox.create_inbox_message (
123 staff = narrative.staff_id,
124 message_type = _('Change notification'),
125 message_category = 'administrative',
126 subject = _('A progress note of yours has been edited.'),
127 patient = narrative['pk_patient']
128 )
129 msg['data'] = _(
130 'Original (by [%s]):\n'
131 '%s\n'
132 '\n'
133 'Edited (by [%s]):\n'
134 '%s'
135 ) % (
136 narrative['modified_by'],
137 narrative['narrative'].strip(),
138 gmStaff.gmCurrentProvider()['short_alias'],
139 val
140 )
141 msg.save()
142
143
144
145
146
147
148
149
150 narrative['narrative'] = val
151 narrative.save()
152 return True
153
154
156
157
158 if patient is None:
159 patient = gmPerson.gmCurrentPatient()
160
161 if not patient.connected:
162 gmDispatcher.send(signal = 'statustext', msg = _('Cannot move progress notes. No active patient.'))
163 return False
164
165 if parent is None:
166 parent = wx.GetApp().GetTopWindow()
167
168 emr = patient.emr
169
170 if encounters is None:
171 all_encs_in_epi = emr.get_encounters(episodes = episodes, skip_empty = True)
172
173 if len(all_encs_in_epi) == 0:
174 return True
175 encounters = gmEncounterWidgets.select_encounters (
176 parent = parent,
177 patient = patient,
178 single_selection = False,
179 encounters = all_encs_in_epi
180 )
181
182 if encounters is None:
183 return True
184
185 if len(encounters) == 0:
186 return True
187
188 notes = emr.get_clin_narrative (
189 encounters = encounters,
190 episodes = episodes
191 )
192
193
194 if move_all:
195 selected_narr = notes
196 else:
197 selected_narr = gmListWidgets.get_choices_from_list (
198 parent = parent,
199 caption = _('Moving progress notes between encounters ...'),
200 single_selection = False,
201 can_return_empty = True,
202 data = notes,
203 msg = _('\n Select the progress notes to move from the list !\n\n'),
204 columns = [_('when'), _('who'), _('type'), _('entry')],
205 choices = [
206 [ narr['date'].strftime('%x %H:%M'),
207 narr['modified_by'],
208 gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
209 narr['narrative'].replace('\n', '/').replace('\r', '/')
210 ] for narr in notes
211 ]
212 )
213
214 if not selected_narr:
215 return True
216
217
218 enc2move2 = gmEncounterWidgets.select_encounters (
219 parent = parent,
220 patient = patient,
221 single_selection = True
222 )
223
224 if not enc2move2:
225 return True
226
227 for narr in selected_narr:
228 narr['pk_encounter'] = enc2move2['pk_encounter']
229 narr.save()
230
231 return True
232
233
235
236
237 if patient is None:
238 patient = gmPerson.gmCurrentPatient()
239
240 if not patient.connected:
241 gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit progress notes. No active patient.'))
242 return False
243
244 if parent is None:
245 parent = wx.GetApp().GetTopWindow()
246
247 emr = patient.emr
248
249 def delete(item):
250 if item is None:
251 return False
252 dlg = gmGuiHelpers.c2ButtonQuestionDlg (
253 parent,
254 -1,
255 caption = _('Deleting progress note'),
256 question = _(
257 'Are you positively sure you want to delete this\n'
258 'progress note from the medical record ?\n'
259 '\n'
260 'Note that even if you chose to delete the entry it will\n'
261 'still be (invisibly) kept in the audit trail to protect\n'
262 'you from litigation because physical deletion is known\n'
263 'to be unlawful in some jurisdictions.\n'
264 ),
265 button_defs = (
266 {'label': _('Delete'), 'tooltip': _('Yes, delete the progress note.'), 'default': False},
267 {'label': _('Cancel'), 'tooltip': _('No, do NOT delete the progress note.'), 'default': True}
268 )
269 )
270 decision = dlg.ShowModal()
271
272 if decision != wx.ID_YES:
273 return False
274
275 gmClinNarrative.delete_clin_narrative(narrative = item['pk_narrative'])
276 return True
277
278 def edit(item):
279 if item is None:
280 return False
281
282 dlg = gmGuiHelpers.cMultilineTextEntryDlg (
283 parent,
284 -1,
285 title = _('Editing progress note'),
286 msg = _('This is the original progress note:'),
287 data = item.format(left_margin = ' ', fancy = True),
288 text = item['narrative']
289 )
290 decision = dlg.ShowModal()
291
292 if decision != wx.ID_SAVE:
293 return False
294
295 val = dlg.value
296 dlg.DestroyLater()
297 if val.strip() == '':
298 return False
299
300 item['narrative'] = val
301 item.save_payload()
302 return True
303
304
305 def refresh(lctrl):
306 notes = emr.get_clin_narrative (
307 encounters = encounters,
308 episodes = episodes,
309 providers = [ gmStaff.gmCurrentProvider()['short_alias'] ]
310 )
311 lctrl.set_string_items(items = [
312 [ narr['date'].strftime('%x %H:%M'),
313 gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
314 narr['narrative'].replace('\n', '/').replace('\r', '/')
315 ] for narr in notes
316 ])
317 lctrl.set_data(data = notes)
318
319
320 gmListWidgets.get_choices_from_list (
321 parent = parent,
322 caption = _('Managing progress notes'),
323 msg = _(
324 '\n'
325 ' This list shows the progress notes by %s.\n'
326 '\n'
327 ) % gmStaff.gmCurrentProvider()['short_alias'],
328 columns = [_('when'), _('type'), _('entry')],
329 single_selection = True,
330 can_return_empty = False,
331 edit_callback = edit,
332 delete_callback = delete,
333 refresh_callback = refresh
334 )
335
336
338
339 if parent is None:
340 parent = wx.GetApp().GetTopWindow()
341
342 search_term_dlg = wx.TextEntryDialog (
343 parent,
344 _('Enter (regex) term to search for across all EMRs:'),
345 caption = _('Text search across all EMRs'),
346 style = wx.OK | wx.CANCEL | wx.CENTRE
347 )
348 result = search_term_dlg.ShowModal()
349
350 if result != wx.ID_OK:
351 return
352
353 wx.BeginBusyCursor()
354 search_term = search_term_dlg.GetValue()
355 search_term_dlg.DestroyLater()
356 results = gmClinNarrative.search_text_across_emrs(search_term = search_term)
357 wx.EndBusyCursor()
358
359 if len(results) == 0:
360 gmGuiHelpers.gm_show_info (
361 _(
362 'Nothing found for search term:\n'
363 ' "%s"'
364 ) % search_term,
365 _('Search results')
366 )
367 return
368
369 items = [ [
370 gmPerson.cPerson(aPK_obj = r['pk_patient'])['description_gender'],
371 r['narrative'],
372 r['src_table']
373 ] for r in results ]
374
375 selected_patient = gmListWidgets.get_choices_from_list (
376 parent = parent,
377 caption = _('Search results for [%s]') % search_term,
378 choices = items,
379 columns = [_('Patient'), _('Match'), _('Match location')],
380 data = [ r['pk_patient'] for r in results ],
381 single_selection = True,
382 can_return_empty = False
383 )
384
385 if selected_patient is None:
386 return
387
388 wx.CallAfter(set_active_patient, patient = gmPerson.cPerson(aPK_obj = selected_patient))
389
390
392
393
394 if patient is None:
395 patient = gmPerson.gmCurrentPatient()
396
397 if not patient.connected:
398 gmDispatcher.send(signal = 'statustext', msg = _('Cannot search EMR. No active patient.'))
399 return False
400
401 if parent is None:
402 parent = wx.GetApp().GetTopWindow()
403
404 search_term_dlg = wx.TextEntryDialog (
405 parent,
406 _('Enter search term:'),
407 caption = _('Text search of entire EMR of active patient'),
408 style = wx.OK | wx.CANCEL | wx.CENTRE
409 )
410 result = search_term_dlg.ShowModal()
411
412 if result != wx.ID_OK:
413 search_term_dlg.DestroyLater()
414 return False
415
416 wx.BeginBusyCursor()
417 val = search_term_dlg.GetValue()
418 search_term_dlg.DestroyLater()
419 emr = patient.emr
420 rows = emr.search_narrative_simple(val)
421 wx.EndBusyCursor()
422
423 if len(rows) == 0:
424 gmGuiHelpers.gm_show_info (
425 _(
426 'Nothing found for search term:\n'
427 ' "%s"'
428 ) % val,
429 _('Search results')
430 )
431 return True
432
433 txt = ''
434 for row in rows:
435 txt += '%s: %s\n' % (
436 row['soap_cat'],
437 row['narrative']
438 )
439
440 txt += ' %s: %s - %s %s\n' % (
441 _('Encounter'),
442 row['encounter_started'].strftime('%x %H:%M'),
443 row['encounter_ended'].strftime('%H:%M'),
444 row['encounter_type']
445 )
446 txt += ' %s: %s\n' % (
447 _('Episode'),
448 row['episode']
449 )
450 txt += ' %s: %s\n\n' % (
451 _('Health issue'),
452 row['health_issue']
453 )
454
455 msg = _(
456 'Search term was: "%s"\n'
457 '\n'
458 'Search results:\n\n'
459 '%s\n'
460 ) % (val, txt)
461
462 dlg = wx.MessageDialog (
463 parent = parent,
464 message = msg,
465 caption = _('Search results for [%s]') % val,
466 style = wx.OK | wx.STAY_ON_TOP
467 )
468 dlg.ShowModal()
469 dlg.DestroyLater()
470
471 return True
472
473
475
476
477 pat = gmPerson.gmCurrentPatient()
478 if not pat.connected:
479 gmDispatcher.send(signal = 'statustext', msg = _('Cannot export EMR for Medistar. No active patient.'))
480 return False
481
482 if encounter is None:
483 encounter = pat.emr.active_encounter
484
485 if parent is None:
486 parent = wx.GetApp().GetTopWindow()
487
488
489 aWildcard = "%s (*.txt)|*.txt|%s (*)|*" % (_("text files"), _("all files"))
490
491 aDefDir = os.path.abspath(os.path.expanduser(os.path.join('~', 'gnumed')))
492
493 fname = '%s-%s-%s-%s-%s.txt' % (
494 'Medistar-MD',
495 time.strftime('%Y-%m-%d',time.localtime()),
496 pat['lastnames'].replace(' ', '-'),
497 pat['firstnames'].replace(' ', '_'),
498 pat.get_formatted_dob(format = '%Y-%m-%d')
499 )
500 dlg = wx.FileDialog (
501 parent = parent,
502 message = _("Save EMR extract for MEDISTAR import as..."),
503 defaultDir = aDefDir,
504 defaultFile = fname,
505 wildcard = aWildcard,
506 style = wx.FD_SAVE
507 )
508 choice = dlg.ShowModal()
509 fname = dlg.GetPath()
510 dlg.DestroyLater()
511 if choice != wx.ID_OK:
512 return False
513
514 wx.BeginBusyCursor()
515 _log.debug('exporting encounter for medistar import to [%s]', fname)
516 exporter = gmPatientExporter.cMedistarSOAPExporter(patient = pat)
517 successful, fname = exporter.save_to_file (
518 filename = fname,
519 encounter = encounter,
520 soap_cats = 'soapu',
521 export_to_import_file = True
522 )
523 if not successful:
524 gmGuiHelpers.gm_show_error (
525 _('Error exporting progress notes for MEDISTAR import.'),
526 _('MEDISTAR progress notes export')
527 )
528 wx.EndBusyCursor()
529 return False
530
531 gmDispatcher.send(signal = 'statustext', msg = _('Successfully exported progress notes into file [%s] for Medistar import.') % fname, beep=False)
532
533 wx.EndBusyCursor()
534 return True
535
536
538
539 pat = gmPerson.gmCurrentPatient()
540 emr = pat.emr
541
542 if parent is None:
543 parent = wx.GetApp().GetTopWindow()
544
545 if soap_cats is None:
546 soap_cats = 'soapu'
547 soap_cats = list(soap_cats)
548 i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
549
550 if msg is None:
551 msg = _('Pick the [%s] narrative you want to use.') % '/'.join(i18n_soap_cats)
552
553
554 def get_tooltip(soap):
555 return soap.format(fancy = True, width = 60)
556
557 def refresh(lctrl):
558 lctrl.secondary_sort_column = 0
559 soap = emr.get_clin_narrative(soap_cats = soap_cats)
560 lctrl.set_string_items ([ [
561 gmDateTime.pydt_strftime(s['date'], '%Y %m %d'),
562 s['modified_by'],
563 gmSoapDefs.soap_cat2l10n[s['soap_cat']],
564 s['narrative'],
565 s['episode'],
566 s['health_issue']
567 ] for s in soap ])
568 lctrl.set_data(soap)
569
570 return gmListWidgets.get_choices_from_list (
571 parent = parent,
572 msg = msg,
573 caption = _('Picking [%s] narrative') % ('/'.join(i18n_soap_cats)),
574 columns = [_('When'), _('Who'), _('Type'), _('Entry'), _('Episode'), _('Issue')],
575 single_selection = False,
576 can_return_empty = False,
577 refresh_callback = refresh,
578 list_tooltip_callback = get_tooltip
579 )
580
581
583
584 pat = gmPerson.gmCurrentPatient()
585 emr = pat.emr
586
587
588
589
590
591
592
593 if parent is None:
594 parent = wx.GetApp().GetTopWindow()
595
596 if soap_cats is None:
597 soap_cats = 'soapu'
598 soap_cats = list(soap_cats)
599 i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
600
601 selected_soap = {}
602
603
604
605 def get_soap_tooltip(soap):
606 return soap.format(fancy = True, width = 60)
607
608 def pick_soap_from_issue(issue):
609
610 if issue is None:
611 return False
612
613 narr_for_issue = emr.get_clin_narrative(issues = [issue['pk_health_issue']], soap_cats = soap_cats)
614
615 if len(narr_for_issue) == 0:
616 gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for this health issue.'))
617 return True
618
619 selected_narr = gmListWidgets.get_choices_from_list (
620 parent = parent,
621 msg = _('Pick the [%s] narrative you want to include in the report.') % '/'.join(i18n_soap_cats),
622 caption = _('Picking [%s] from %s%s%s') % (
623 '/'.join(i18n_soap_cats),
624 gmTools.u_left_double_angle_quote,
625 issue['description'],
626 gmTools.u_right_double_angle_quote
627 ),
628 columns = [_('When'), _('Who'), _('Type'), _('Entry')],
629 choices = [ [
630 gmDateTime.pydt_strftime(narr['date'], '%Y %b %d %H:%M', accuracy = gmDateTime.acc_minutes),
631 narr['modified_by'],
632 gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
633 narr['narrative'].replace('\n', '//').replace('\r', '//')
634 ] for narr in narr_for_issue ],
635 data = narr_for_issue,
636
637
638 single_selection = False,
639 can_return_empty = False,
640 list_tooltip_callback = get_soap_tooltip
641 )
642
643 if selected_narr is None:
644 return True
645
646 for narr in selected_narr:
647 selected_soap[narr['pk_narrative']] = narr
648
649 return True
650
651 def edit_issue(issue):
652 return gmEMRStructWidgets.edit_health_issue(parent = parent, issue = issue)
653
654 def refresh_issues(lctrl):
655
656 issues = emr.health_issues
657 lctrl.set_string_items ([ [
658 gmTools.bool2subst(i['is_confidential'], _('!! CONFIDENTIAL !!'), ''),
659 i['description'],
660 gmTools.bool2subst(i['is_active'], _('active'), _('inactive'))
661 ] for i in issues
662 ])
663 lctrl.set_data(issues)
664
665 def get_issue_tooltip(issue):
666 return issue.format (
667 patient = pat,
668 with_encounters = False,
669 with_medications = False,
670 with_hospital_stays = False,
671 with_procedures = False,
672 with_family_history = False,
673 with_documents = False,
674 with_tests = False,
675 with_vaccinations = False
676 )
677
678
679
680 issues_picked_from = gmListWidgets.get_choices_from_list (
681 parent = parent,
682 msg = _('\n Select the issue you want to report on.'),
683 caption = _('Picking [%s] from health issues') % '/'.join(i18n_soap_cats),
684 columns = [_('Privacy'), _('Issue'), _('Status')],
685 edit_callback = edit_issue,
686 refresh_callback = refresh_issues,
687 single_selection = True,
688 can_return_empty = True,
689 ignore_OK_button = False,
690 left_extra_button = (
691 _('&Pick notes'),
692 _('Pick [%s] entries from selected health issue') % '/'.join(i18n_soap_cats),
693 pick_soap_from_issue
694 ),
695 list_tooltip_callback = get_issue_tooltip
696 )
697
698 if issues_picked_from is None:
699 return []
700
701 return selected_soap.values()
702
703
704
705
706
707
708
709
710
712
713 pat = gmPerson.gmCurrentPatient()
714 emr = pat.emr
715
716 all_epis = [ epi for epi in emr.get_episodes(order_by = 'description') if epi.has_narrative ]
717 if len(all_epis) == 0:
718 gmDispatcher.send(signal = 'statustext', msg = _('No episodes with progress notes found.'))
719 return []
720
721 if parent is None:
722 parent = wx.GetApp().GetTopWindow()
723
724 if soap_cats is None:
725 soap_cats = 'soapu'
726 soap_cats = list(soap_cats)
727 i18n_soap_cats = [ gmSoapDefs.soap_cat2l10n[cat].upper() for cat in soap_cats ]
728
729 selected_soap = {}
730
731
732
733 def get_soap_tooltip(soap):
734 return soap.format(fancy = True, width = 60)
735
736 def pick_soap_from_episode(episode):
737
738 if episode is None:
739 return False
740
741 narr_for_epi = emr.get_clin_narrative(episodes = [episode['pk_episode']], soap_cats = soap_cats)
742
743 if len(narr_for_epi) == 0:
744 gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for selected episode.'))
745 return True
746
747 selected_narr = gmListWidgets.get_choices_from_list (
748 parent = parent,
749 msg = _('Pick the [%s] narrative you want to include in the report.') % '/'.join(i18n_soap_cats),
750 caption = _('Picking [%s] from %s%s%s') % (
751 '/'.join(i18n_soap_cats),
752 gmTools.u_left_double_angle_quote,
753 episode['description'],
754 gmTools.u_right_double_angle_quote
755 ),
756 columns = [_('When'), _('Who'), _('Type'), _('Entry')],
757 choices = [ [
758 gmDateTime.pydt_strftime(narr['date'], '%Y %b %d %H:%M', accuracy = gmDateTime.acc_minutes),
759 narr['modified_by'],
760 gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
761 narr['narrative'].replace('\n', '//').replace('\r', '//')
762 ] for narr in narr_for_epi ],
763 data = narr_for_epi,
764
765
766 single_selection = False,
767 can_return_empty = False,
768 list_tooltip_callback = get_soap_tooltip
769 )
770
771 if selected_narr is None:
772 return True
773
774 for narr in selected_narr:
775 selected_soap[narr['pk_narrative']] = narr
776
777 return True
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794 def edit_episode(episode):
795 return gmEMRStructWidgets.edit_episode(parent = parent, episode = episode)
796
797 def refresh_episodes(lctrl):
798 all_epis = [ epi for epi in emr.get_episodes(order_by = 'description') if epi.has_narrative ]
799 lctrl.set_string_items ([ [
800 '%s%s' % (e['description'], gmTools.coalesce(e['health_issue'], '', ' (%s)')),
801 gmTools.bool2subst(e['episode_open'], _('open'), _('closed'))
802 ] for e in all_epis
803 ])
804 lctrl.set_data(all_epis)
805
806 def get_episode_tooltip(episode):
807 return episode.format (
808 patient = pat,
809 with_encounters = False,
810 with_documents = False,
811 with_hospital_stays = False,
812 with_procedures = False,
813 with_family_history = False,
814 with_tests = False,
815 with_vaccinations = False
816 )
817
818
819
820 epis_picked_from = gmListWidgets.get_choices_from_list (
821 parent = parent,
822 msg = _('\n Select the episode you want to report on.'),
823 caption = _('Picking [%s] from episodes') % '/'.join(i18n_soap_cats),
824 columns = [_('Episode'), _('Status')],
825 edit_callback = edit_episode,
826 refresh_callback = refresh_episodes,
827 single_selection = True,
828 can_return_empty = True,
829 ignore_OK_button = False,
830 left_extra_button = (
831 _('&Pick notes'),
832 _('Pick [%s] entries from selected episode') % '/'.join(i18n_soap_cats),
833 pick_soap_from_episode
834 ),
835 list_tooltip_callback = get_episode_tooltip
836 )
837
838 if epis_picked_from is None:
839 return []
840
841 return selected_soap.values()
842
843
844
845
846
847
848
849
850
852 """soap_cats needs to be a list"""
853
854 pat = gmPerson.gmCurrentPatient()
855 emr = pat.emr
856
857 if parent is None:
858 parent = wx.GetApp().GetTopWindow()
859
860 selected_soap = {}
861 selected_issue_pks = []
862 selected_episode_pks = []
863 selected_narrative_pks = []
864
865 while 1:
866
867 all_issues = emr.get_health_issues()
868 all_issues.insert(0, gmEMRStructItems.get_dummy_health_issue())
869 dlg = gmEMRStructWidgets.cIssueListSelectorDlg (
870 parent = parent,
871 id = -1,
872 issues = all_issues,
873 msg = _('\n In the list below mark the health issues you want to report on.\n')
874 )
875 selection_idxs = []
876 for idx in range(len(all_issues)):
877 if all_issues[idx]['pk_health_issue'] in selected_issue_pks:
878 selection_idxs.append(idx)
879 if len(selection_idxs) != 0:
880 dlg.set_selections(selections = selection_idxs)
881 btn_pressed = dlg.ShowModal()
882 selected_issues = dlg.get_selected_item_data()
883 dlg.DestroyLater()
884
885 if btn_pressed == wx.ID_CANCEL:
886 return selected_soap.values()
887
888 selected_issue_pks = [ i['pk_health_issue'] for i in selected_issues ]
889
890 while 1:
891
892 all_epis = emr.get_episodes(issues = selected_issue_pks)
893
894 if len(all_epis) == 0:
895 gmDispatcher.send(signal = 'statustext', msg = _('No episodes recorded for the health issues selected.'))
896 break
897
898 dlg = gmEMRStructWidgets.cEpisodeListSelectorDlg (
899 parent = parent,
900 id = -1,
901 episodes = all_epis,
902 msg = _(
903 '\n These are the episodes known for the health issues just selected.\n\n'
904 ' Now, mark the the episodes you want to report on.\n'
905 )
906 )
907 selection_idxs = []
908 for idx in range(len(all_epis)):
909 if all_epis[idx]['pk_episode'] in selected_episode_pks:
910 selection_idxs.append(idx)
911 if len(selection_idxs) != 0:
912 dlg.set_selections(selections = selection_idxs)
913 btn_pressed = dlg.ShowModal()
914 selected_epis = dlg.get_selected_item_data()
915 dlg.DestroyLater()
916
917 if btn_pressed == wx.ID_CANCEL:
918 break
919
920 selected_episode_pks = [ i['pk_episode'] for i in selected_epis ]
921
922
923 all_narr = emr.get_clin_narrative(episodes = selected_episode_pks, soap_cats = soap_cats)
924
925 if len(all_narr) == 0:
926 gmDispatcher.send(signal = 'statustext', msg = _('No narrative available for selected episodes.'))
927 continue
928
929 dlg = cNarrativeListSelectorDlg (
930 parent = parent,
931 id = -1,
932 narrative = all_narr,
933 msg = _(
934 '\n This is the narrative (type %s) for the chosen episodes.\n\n'
935 ' Now, mark the entries you want to include in your report.\n'
936 ) % '/'.join([ gmSoapDefs.soap_cat2l10n[cat] for cat in gmTools.coalesce(soap_cats, list('soapu')) ])
937 )
938 selection_idxs = []
939 for idx in range(len(all_narr)):
940 if all_narr[idx]['pk_narrative'] in selected_narrative_pks:
941 selection_idxs.append(idx)
942 if len(selection_idxs) != 0:
943 dlg.set_selections(selections = selection_idxs)
944 btn_pressed = dlg.ShowModal()
945 selected_narr = dlg.get_selected_item_data()
946 dlg.DestroyLater()
947
948 if btn_pressed == wx.ID_CANCEL:
949 continue
950
951 selected_narrative_pks = [ i['pk_narrative'] for i in selected_narr ]
952 for narr in selected_narr:
953 selected_soap[narr['pk_narrative']] = narr
954
955
956
957
958 if __name__ == '__main__':
959
960 if len(sys.argv) < 2:
961 sys.exit()
962
963 if sys.argv[1] != 'test':
964 sys.exit()
965
966 from Gnumed.business import gmPersonSearch
967
968 gmI18N.activate_locale()
969 gmI18N.install_domain(domain = 'gnumed')
970
971
980
989
990
991 test_select_narrative()
992