Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mechanism to migrate a patient's visit locations if needed #15

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.openmrs.module.imbemr.migrations;

import org.openmrs.Location;
import org.openmrs.Patient;
import org.openmrs.Visit;
import org.openmrs.api.VisitService;
import org.openmrs.module.emrapi.adt.AdtService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* This class exists to migrate visit locations where possible to ensure the locations
* associated with Visits are valid Visit Locations
*/
@Component
public class VisitLocationMigrator {

private final Logger log = LoggerFactory.getLogger(getClass());

private final VisitService visitService;

private final AdtService adtService;

public VisitLocationMigrator(@Autowired VisitService visitService, @Autowired AdtService adtService) {
this.visitService = visitService;
this.adtService = adtService;
}

public Map<Visit, Location> getVisitsThatRequireLocationMigration(Patient patient) {
Map<Visit, Location> ret = new HashMap<>();
List<Location> visitLocations = adtService.getAllLocationsThatSupportVisits();
List<Visit> visits = visitService.getVisitsByPatient(patient);
for (Visit visit : visits) {
Location existingVisitLocation = visit.getLocation();
Location correctVisitLocation = getVisitLocation(existingVisitLocation, visitLocations);
if (correctVisitLocation != null && !correctVisitLocation.equals(existingVisitLocation)) {
ret.put(visit, correctVisitLocation);
}
}
return ret;
}

public void migrateVisitLocationsForPatient(Patient patient) {
Map<Visit, Location> migrationRequired = getVisitsThatRequireLocationMigration(patient);
if (migrationRequired.isEmpty()) {
log.debug("Patient " + patient.getUuid() + " does not have any visits that require migration");
return;
}
log.warn("Patient " + patient.getUuid() + " has " + migrationRequired.size() + " visits that require migration");
for (Visit visit : migrationRequired.keySet()) {
migrationVisitLocation(visit, migrationRequired.get(visit));
}
log.warn("Migration completed for patient");
}

public void migrationVisitLocation(Visit visit, Location correctLocation) {
log.warn("Updating location for visit " + visit.getUuid() + " from " + getLocationName(visit.getLocation()) + " to " + getLocationName(correctLocation));
visit.setLocation(correctLocation);
visitService.saveVisit(visit);
}

public Location getVisitLocation(Location location, List<Location> allowedLocations) {
if (allowedLocations.contains(location)) {
return location;
}
if (location.getParentLocation() != null) {
return getVisitLocation(location.getParentLocation(), allowedLocations);
}
return null;
}

private String getLocationName(Location location) {
return location == null ? "null" : location.getName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.openmrs.module.imbemr.page.controller.patient;

import org.openmrs.Patient;
import org.openmrs.api.context.Context;
import org.openmrs.module.emrapi.patient.PatientDomainWrapper;
import org.openmrs.module.imbemr.migrations.VisitLocationMigrator;
import org.openmrs.ui.framework.UiUtils;
import org.openmrs.ui.framework.annotation.InjectBeans;
import org.openmrs.ui.framework.annotation.SpringBean;
import org.openmrs.ui.framework.page.PageModel;
import org.openmrs.util.PrivilegeConstants;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

public class MigrateVisitLocationsPageController {

public String get(PageModel model,
@InjectBeans PatientDomainWrapper patientDomainWrapper,
@RequestParam(value = "patientId") Patient patient,
@SpringBean VisitLocationMigrator visitLocationMigrator) {

if (!Context.hasPrivilege(PrivilegeConstants.EDIT_VISITS)) {
return "redirect:/index.htm";
}

patientDomainWrapper.setPatient(patient);
model.addAttribute("patient", patientDomainWrapper);
model.addAttribute("visitsToMigrate", visitLocationMigrator.getVisitsThatRequireLocationMigration(patient));
return "patient/migrateVisitLocations";
}

public String post(PageModel model, UiUtils ui, HttpServletRequest request,
@InjectBeans PatientDomainWrapper patientDomainWrapper,
@RequestParam(value = "patientId") Patient patient,
@SpringBean VisitLocationMigrator visitLocationMigrator) {

patientDomainWrapper.setPatient(patient);

try {
visitLocationMigrator.migrateVisitLocationsForPatient(patient);
}
catch (Exception e) {
request.getSession().setAttribute("emr.errorMessage", e.getMessage());
model.addAttribute("patient", patientDomainWrapper);
model.addAttribute("visitsToMigrate", visitLocationMigrator.getVisitsThatRequireLocationMigration(patient));
return "patient/migrateVisitLocations";
}
request.getSession().setAttribute("emr.infoMessage", "Visits migrated successfully");
request.getSession().setAttribute("emr.toastMessage", "true");
Map<String, Object> params = new HashMap<>();
params.put("patientId", patient.getUuid());
return "redirect:" + ui.pageLink("coreapps", "clinicianfacing/patient", params);
}
}
57 changes: 57 additions & 0 deletions omod/src/main/webapp/pages/patient/migrateVisitLocations.gsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<%
ui.decorateWith("appui", "standardEmrPage")
%>

${ ui.includeFragment("coreapps", "patientHeader", [ patient: patient.patient ]) }

<h3>Migrate Visit Locations</h3>

<% if (visitsToMigrate.size() == 0) { %>

This patient has no visits that need to be migrated

<% } else { %>

<table>
<thead>
<tr>
<th>Visit Date</th>
<th>Encounters</th>
<th>Current Location</th>
<th>Correct Location</th>
</tr>
</thead>
<tbody>

<% visitsToMigrate.keySet().each { visit -> %>
<tr>
<td>
${ ui.format(visit.startDatetime) }
</td>
<td>
<% visit.encounters.eachWithIndex{ encounter, index -> %>
${index == 0 ? "" : "<br/>"}
${ui.format(encounter.encounterDatetime)}:
${ui.format(encounter.encounterType)} at ${ui.format(encounter.location)}
<% } %>
</td>
<td>
${ ui.format(visit.location) }
</td>
<td>
${ ui.format(visitsToMigrate.get(visit)) }
</td>
</tr>
<% } %>
</tbody>
</table>
<div>
<form method="post">
<input type="hidden" name="patientId" value="${patient.patient.patientId}" />
<input type="submit" class="submit" value="Migrate"/>
</form>
</div>
<% } %>