Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.openmrs.module</groupId>
<artifactId>o3forms-omod</artifactId>
<version>${o3FormsVersion}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
Expand Down Expand Up @@ -115,6 +122,31 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.openmrs.module</groupId>
<artifactId>webservices.rest-omod-common</artifactId>
<version>${openmrsWebRestVersion}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -154,5 +186,17 @@
<filtering>false</filtering>
</testResource>
</testResources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExclude>com.fasterxml.jackson.datatype:jackson-datatype-jsr310</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.openmrs.module.patientdocuments.common.PatientDocumentsConstants.MODULE_NAME;

import org.openmrs.module.BaseModuleActivator;
import org.openmrs.module.patientdocuments.reports.EncounterPdfReportManager;
import org.openmrs.module.patientdocuments.reports.PatientIdStickerReportManager;
import org.openmrs.module.reporting.report.manager.ReportManagerUtil;
import org.slf4j.Logger;
Expand Down Expand Up @@ -42,6 +43,17 @@ public void started() {
catch (Exception e) {
log.error("Failed to set up report '{}'", patientIdStickerReportName, e);
}

EncounterPdfReportManager encounterReportManager = new EncounterPdfReportManager();
String encounterPdfReportName = encounterReportManager.getName();

log.info("Setting up report: {} ...", encounterPdfReportName);
try {
ReportManagerUtil.setupReport(encounterReportManager);
log.info("Successfully set up report: {}", encounterPdfReportName);
} catch (Exception e) {
log.error("Failed to set up report '{}'", encounterPdfReportName, e);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,17 @@
*/
package org.openmrs.module.patientdocuments.common;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import org.apache.commons.io.IOUtils;
import org.openmrs.util.OpenmrsClassLoader;

import java.io.InputStream;

public class Helper {

/**
* Given a location on the classpath, return the contents of this resource as a String
*/
public static String getStringFromResource(String resourceName) {
InputStream is = null;

public static InputStream getInputStreamByResource(String resourceName) {
try {
is = OpenmrsClassLoader.getInstance().getResourceAsStream(resourceName);
return IOUtils.toString(is, StandardCharsets.UTF_8.name());
}
catch (Exception e) {
return OpenmrsClassLoader.getInstance().getResourceAsStream(resourceName);
} catch (Exception e) {
throw new IllegalArgumentException("Unable to load resource: " + resourceName, e);
}
finally {
IOUtils.closeQuietly(is);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,18 @@ public class PatientDocumentsConstants {
* The path to the style sheet for Patient History reports.
*/
public static final String PATIENT_ID_STICKER_XSL_PATH = "patientIdStickerFopStylesheet.xsl";

public static final String DEFAULT_ENCOUNTER_FORM_XSL_PATH = "defaultEncounterFormFopStylesheet.xsl";

public static final String ENCOUNTER_PRINTING_HEADER_PREFIX = "report.encounterPrinting.header.";

public static final String ENCOUNTER_PRINTING_FOOTER_PREFIX = "report.encounterPrinting.footer.";

public static final String ENCOUNTER_PRINTING_STYLESHEET_KEY = "report.encounterPrinting.stylesheet";

public static final String ENCOUNTER_PRINTING_LOGO_PATH_KEY = "report.encounterPrinting.logopath";

public static final String NO_DATA_RECORDED_PLACEHOLDER = "No data recorded";

public static final String MISSING_VALUE_PLACEHOLDER = "-";
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@
public class PatientDocumentsPrivilegeConstants {

public static final String VIEW_PATIENT_ID_STICKER = "App: Can generate a Patient Identity Sticker";


public static final String PRINT_ENCOUNTER_FORMS_PRIVILEGE = "App: Print encounter forms";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.patientdocuments.renderer;

import org.apache.commons.lang3.StringUtils;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.openmrs.Encounter;
import org.openmrs.annotation.Handler;
import org.openmrs.api.EncounterService;
import org.openmrs.api.context.Context;
import org.openmrs.module.initializer.api.InitializerService;
import org.openmrs.module.patientdocuments.common.Helper;
import org.openmrs.module.patientdocuments.common.PatientDocumentsConstants;
import org.openmrs.module.patientdocuments.reports.EncounterPdfReportManager;
import org.openmrs.module.reporting.report.ReportData;
import org.openmrs.module.reporting.report.ReportRequest;
import org.openmrs.module.reporting.report.renderer.RenderingException;
import org.openmrs.module.reporting.report.renderer.ReportDesignRenderer;
import org.springframework.stereotype.Component;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

@Component
@Handler
public class EncounterPdfReportRenderer extends ReportDesignRenderer {

@Override
public String getFilename(ReportRequest request) {
return "EncountersReport.pdf";
}

@Override
public String getRenderedContentType(ReportRequest request) {
return "application/pdf";
}

@Override
public void render(ReportData results, String argument, OutputStream out) throws RenderingException {
try {
String encounterUuidsParam = (String) getReportParam(results, EncounterPdfReportManager.ENCOUNTER_UUIDS_PARAM);
if (StringUtils.isBlank(encounterUuidsParam)) {
throw new RenderingException("No encounter UUIDs provided");
}

List<Encounter> encounters = collectEncounters(encounterUuidsParam);
Locale reportLocale = (Locale) getReportParam(results, EncounterPdfReportManager.ENCOUNTER_LOCALE_PARAM);
EncounterPrintingContext printingContext = new EncounterPrintingContext(encounters, reportLocale);
String encountersXml = new EncounterXmlBuilder().build(printingContext);
transformXmlToPdf(encountersXml, out);
} catch (Exception e) {
throw new RenderingException("Error generating PDF: " + e.getMessage(), e);
}
}

private Object getReportParam(ReportData data, String paramName) {
return data.getContext().getParameterValue(paramName);
}

private List<Encounter> collectEncounters(String encounterUuids) {
EncounterService encounterService = Context.getEncounterService();
String[] uuids = encounterUuids.split(",");
List<Encounter> encounters = new ArrayList<>();
for (String uuid : uuids) {
Encounter encounter = encounterService.getEncounterByUuid(uuid.trim());
if (encounter != null) {
encounters.add(encounter);
}
}

return encounters;
}

private void transformXmlToPdf(String xmlData, OutputStream outStream) throws Exception {
FopFactory fopFactory = FopFactory.newInstance(new URI("."));
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, outStream);

String stylesheetName = getStylesheetName();
try (InputStream xslStream = Helper.getInputStreamByResource(stylesheetName)) {
if (xslStream == null) {
throw new FileNotFoundException("Stylesheet not found at " + stylesheetName);
}

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xslStream));
Source src = new StreamSource(new StringReader(xmlData));
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
}
}

private String getStylesheetName() {
String stylesheetName = Context.getService(InitializerService.class).getValueFromKey(PatientDocumentsConstants.ENCOUNTER_PRINTING_STYLESHEET_KEY);
if (StringUtils.isBlank(stylesheetName)) {
stylesheetName = PatientDocumentsConstants.DEFAULT_ENCOUNTER_FORM_XSL_PATH;
}
return stylesheetName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.patientdocuments.renderer;

import org.openmrs.Encounter;

import java.util.List;
import java.util.Locale;

public class EncounterPrintingContext {
private List<Encounter> encounters;

private Locale locale;

public EncounterPrintingContext(List<Encounter> encounters, Locale locale) {
this.encounters = encounters;
this.locale = locale;
}

public List<Encounter> getEncounters() {
return encounters;
}

public void setEncounters(List<Encounter> encounters) {
this.encounters = encounters;
}

public Locale getLocale() {
return locale;
}

public void setLocale(Locale locale) {
this.locale = locale;
}
}

Loading