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

O3-3193: REST API for EMR API ADT functionality #231

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Changes from 1 commit
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,74 @@
package org.openmrs.module.emrapi.web.controller;

import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Minutes;
import org.openmrs.Location;
import org.openmrs.Visit;
import org.openmrs.module.emrapi.adt.AdtService;
import org.openmrs.module.emrapi.visit.VisitDomainWrapper;
import org.openmrs.module.webservices.rest.SimpleObject;
import org.openmrs.module.webservices.rest.web.ConversionUtil;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/rest/emrapi/inpatient")
public class InpatientVisitsController {

@Autowired
private AdtService adtService;

@RequestMapping(method = RequestMethod.GET, value = "/visits")
@ResponseBody
public List<SimpleObject> getInpatientVisits(@RequestParam(value = "currentLocation") Location currentLocation) {
mseaton marked this conversation as resolved.
Show resolved Hide resolved

// TODO expand to allow null current location

// TODO handle null response if possible
// TODO this getInpatentVisits method is almost certainly not performant enough for production use and will likely need to be refactored into a HQL query
List<VisitDomainWrapper> visits = adtService.getInpatientVisits(adtService.getLocationThatSupportsVisits(currentLocation), currentLocation);

// TODO type this?
List<SimpleObject> response = new ArrayList<SimpleObject>();

for (VisitDomainWrapper visit : visits) {
SimpleObject inpatientVisit = new SimpleObject();
inpatientVisit.put("visit", ConversionUtil.convertToRepresentation(visit.getVisit(), Representation.DEFAULT));
mseaton marked this conversation as resolved.
Show resolved Hide resolved
inpatientVisit.put("patient", ConversionUtil.convertToRepresentation(visit.getVisit().getPatient(), Representation.DEFAULT));
inpatientVisit.put("currentLocation", ConversionUtil.convertToRepresentation(currentLocation, Representation.DEFAULT));
inpatientVisit.put("timeSinceAdmissionInMinutes", Minutes.minutesBetween(new DateTime(visit.getAdmissionEncounter().getEncounterDatetime()), new DateTime()).getMinutes());
inpatientVisit.put("timeOnWardInMinutes", Minutes.minutesBetween(new DateTime(visit.getLatestAdtEncounter().getEncounterDatetime()), new DateTime()).getMinutes()); // TODO: assumption, an ADT ecounter always results in change of ward?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this wouldn't cover the (probably rare) case of a bed swap within the same ward, assuming a TRANSFER encounter is used for this. Though if a different encounter type were used, then this would work. I tried to describe this situation in the ticket, but it wasn't very clear, and it's something we can discuss

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that would be a limitation. I just dropped in those "timeSince" and "timeWard" values during my last few minutes of work on Monday to has some examples of parameter, (and there some satisfaction in seeing them work without much extra work!). I think we are going to need to rewrite the underlying service method using a query, and we may want to tackle calculating these values as part of that, but if we don't, it should should be very straightforward to move these two time calculations out of the controller and into the VDW and handle the edge case you describe there by iterating over encounters and comparing locations. In fact, easy enough that it probably makes sense for me to move them now.

response.add(inpatientVisit);
}

return response;
}

@RequestMapping(method = RequestMethod.GET, value = "/admissionRequests")
@ResponseBody
public List<SimpleObject> getVisitsAwaitingAdmission(@RequestParam("admissionLocation") Location admissionLocation) {

// TODO note that this service method *only* returns admission requests, while we will need to expand this to include transfer requests (which will be slightly non-trivial)
// TODO note also that this service method does *not* actually limit by admission location; we will need to expand the underlying service method/hql query to do this
List<Visit> visits = adtService.getVisitsAwaitingAdmission(admissionLocation, null, null);
List<SimpleObject> response = new ArrayList<SimpleObject>();
for (Visit visit : visits) {
SimpleObject inpatientVisit = new SimpleObject();
inpatientVisit.put("visit", ConversionUtil.convertToRepresentation(visit, Representation.DEFAULT));
mseaton marked this conversation as resolved.
Show resolved Hide resolved
inpatientVisit.put("patient", ConversionUtil.convertToRepresentation(visit.getPatient(), Representation.DEFAULT));
response.add(inpatientVisit);
}
return response;
}
}



Loading