What is the best way to do a clinical summary?

I need to create a clinical summary. What is the best way to do this, that will be fully supported going forward? Is there a way to do this natively in the Reporting Module? And then just adding a link to the OpenMRS 2.x UI, or navigating to a specific URL?

I looked at the Patient Summary Module. It looks like it doesn’t support the OpenMRS 2.x UI. I also thought maybe I could just manually add a link to a specific URL, but when I try to design my template (minimal with just text, not even adding in the $data.name, etc), the preview gives an error…

org.openmrs.module.reporting.report.renderer.ReportRenderer.getRenderedContentType(Lorg/openmrs/module/reporting/report/definition/ReportDefinition;Ljava/lang/String;)Ljava/lang/String;

Also, on the legacy patient dashboard, I get an error under the Patient Summaries tab…

Please fix all errors and try again. 
javax.servlet.jsp.JspException: javax.el.ELException: Error reading 'contentType' on type org.openmrs.module.patientsummary.PatientSummaryTemplate
javax.el.BeanELResolver.getValue(BeanELResolver.java:98)
org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:104)
org.apache.el.parser.AstValue.getValue(AstValue.java:182)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:944)
org.apache.jsp.WEB_002dINF.view.module.patientsummary.portlets.patientSummaries_jsp._jspService(patientSummaries_jsp.java:134)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.JspClassLoaderFilter.doFilter(JspClassLoaderFilter.java:47)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:229)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
org.apache.taglibs.standard.tag.common.core.ImportSupport.acquireString(ImportSupport.java:296)
org.apache.taglibs.standard.tag.common.core.ImportSupport.doEndTag(ImportSupport.java:161)
org.openmrs.web.taglib.PortletTag.doEndTag(PortletTag.java:100)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_openmrs_005fportlet_005f8(patientDashboardForm_jsp.java:6824)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_c_005fotherwise_005f5(patientDashboardForm_jsp.java:6766)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_c_005fchoose_005f5(patientDashboardForm_jsp.java:6700)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_c_005fcatch_005f0(patientDashboardForm_jsp.java:6660)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_openmrs_005fhasPrivilege_005f20(patientDashboardForm_jsp.java:6621)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspx_meth_openmrs_005fextensionPoint_005f11(patientDashboardForm_jsp.java:6583)
org.apache.jsp.WEB_002dINF.view.patientDashboardForm_jsp._jspService(patientDashboardForm_jsp.java:904)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.JspClassLoaderFilter.doFilter(JspClassLoaderFilter.java:47)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:61)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:72)
org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:54)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:109)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:230)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:745)

@mseaton, Is there a compatibility problem between Patient Summary Module and OpenMRS 1.11.4?

Shall I give in and just use BIRT or Jasper, or is there another preferred way to do this?

I think going forwards, you should use the reporting module to create datasets that will feed your clinical summary. Once this is done, then remaining part is just a renderer for it.

Hi James,

There isn’t a great way that I know of without programming. The patientsummary module was an initial attempt to support this, though the module is not in use by anyone that I know of (and hence is not actively supported). From your error report below, I think there is likely an incompatibility introduced by the reporting module ( there was a backwards-incompatible change introduced a while back here https://github.com/openmrs/openmrs-module-reporting/commit/fa3dd62b4ace6f4ae485c20067cb87c5dbce29ce#diff-1dfd740e61d1cbb08f37f93800d9b189 ). It would be pretty straightforward to fix this in the patientsummary module. Want to create a ticket and ping me on it?

Thanks, Mike

Thanks @mseaton. I have created the ticket for posterity sake, but I will try just using other features (Datasets and Renders) of the reporting module like @dkayiwa suggests. I don’t want to be stuck using something that nobody else is using (that may not be supported) if there is another option.

Smart move.

That being said, at it’s heart the patientsummary module is simply a wrapper around reporting Datasets and Renderers :slight_smile:

The patientsummary module creates the following wrapper objects:

  • PatientSummaryReportDefinition (just a custom Report Definition that is fixed to contain a single Patient Data Set Definition)
  • PatientSummaryTemplate (just a wrapper around a Report Design)

It then adds some service methods and UI pages (in the 1.x UI) to allow for more easily managing / editing these. And it attaches to 1.x UI extension points for allowing patient summaries to appear as new tabs on the patient dashboard based on global property configuration.

It is all described a bit better here: https://wiki.openmrs.org/display/docs/Patient+Summary+Module

So, if you are working in the 2.x UI, and can independently find a way to add a page that runs a Report containing a single PatientDataSetDefinition and renders it using a TextTemplateRenderer and outputs the resulting html to the page, then you’ve pretty much achieved what the patientsummary module is capable of doing.

Mike

@mseaton, thanks for your continued recommendations and assistance.

One quick question, is it possible to specify parameters for running a report via the URL? Either for the Reporting UI or the legacy Reporting Module? Specifically I’d like to specify the patientId and report renderer, and have it run the report immediately.

FYI: It appears the Reporting UI Module needs some work to handle parameters of Person and Location. I’ve created a ticket…

Hi James,

I’m not sure about that - I’d have to do a little investigation. @darius might know more offhand.

Mike

I do not know offhand.

Has anyone had a chance to look and see if it’s possible to specify parameters for running a report via the URL? Shall I create a ticket for this?

Thanks @mseaton and @darius for your quick answers.

Peeking at the code in the reportingui module I see:

If you POST to …/reportingui/runReport.page with request parameters for

  • reportDefinition … should be a UUID
  • renderingMode … not sure what this should be, but you can probably find out by viewing source on the run report page

and for the report parameters, you specify them with request parameters like “parameterValues[startDate]”

Good luck!

This topic keeps coming up. Eventually I just made a report and template with the reporting module. It’s available on the wiki at… How to create a Patient Clinical Summary using Reporting Module

I used same template as described but this Patient Clinical Summary Report does not print anything from admission, transfer, discharge, visit note, vitals, diagnosis, allergies, appointments and visits of patient. Patient Clinical Summary Report should at least print the latest records from each with short past history.

@hpardess do you have a sample of how this would look like?

The template is there as an example of what some implementation might need. Each implementation will be different. Feel free to make a more comprehensive template (based on your exact needs) and add it to the documentation as well.

@arbaughj , @hpardess -You can also try this example and see if it helps. The requirement was to add a link in the reference application patient dashboard and allow users to download a patient summary that shows the demographics and encounters for the patient.

The #evaluatePatientSummaryTemplate method in the patient summary module makes it easy to generate the summary since it takes in a single patient id and evaluates the report just for that patient.

The report could be like this,

@hpardess the first step here would be to create various dataset definitions in the reporting module to represent data in the different report sections.

@hpardess One of the goals of the Reference application is to get a pre-built report - can you provide me with an example of a completed patient summary that can be used as a starting point

Please refer to bellow link for a sample report about visit. How to print a specific visit details of a Patient from visits page? OpenMRS 2x RefApp 2x - #3 by hpardess