package femr.ui.controllers; import com.google.inject.Inject; import femr.business.services.core.*; import femr.common.dtos.CurrentUser; import femr.common.dtos.ServiceResponse; import femr.common.models.*; import femr.data.models.mysql.Roles; import femr.ui.helpers.security.AllowedRoles; import femr.ui.helpers.security.FEMRAuthenticated; import femr.ui.models.pharmacy.*; import femr.ui.views.html.pharmacies.index; import femr.ui.views.html.pharmacies.edit; import femr.util.stringhelpers.StringUtils; import play.data.Form; import play.data.FormFactory; import play.mvc.Controller; import play.mvc.Result; import play.mvc.Security; import java.util.HashMap; import java.util.List; import java.util.Map; @Security.Authenticated(FEMRAuthenticated.class) @AllowedRoles({Roles.PHYSICIAN, Roles.PHARMACIST, Roles.NURSE}) public class PharmaciesController extends Controller { private final FormFactory formFactory; private final IEncounterService encounterService; private final IMedicationService medicationService; private final ISessionService sessionService; private final ISearchService searchService; private final IInventoryService inventoryService; @Inject public PharmaciesController(FormFactory formFactory, IEncounterService encounterService, IMedicationService medicationService, ISessionService sessionService, ISearchService searchService, IInventoryService inventoryService) { this.formFactory = formFactory; this.encounterService = encounterService; this.medicationService = medicationService; this.sessionService = sessionService; this.searchService = searchService; this.inventoryService = inventoryService; } public Result indexGet() { CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession(); return ok(index.render(currentUserSession, null, 0)); } /** * Validates the patient ID that the user entered * * @return redirect to editGet */ public Result indexPost() { CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession(); String queryString_id = request().body().asFormUrlEncoded().get("id")[0]; ServiceResponse<Integer> idQueryStringResponse = searchService.parseIdFromQueryString(queryString_id); if (idQueryStringResponse.hasErrors()) { return ok(index.render(currentUserSession, idQueryStringResponse.getErrors().get(""), 0)); } Integer patientId = idQueryStringResponse.getResponseObject(); //get the patient's encounter ServiceResponse<PatientEncounterItem> patientEncounterItemServiceResponse = searchService.retrieveRecentPatientEncounterItemByPatientId(patientId); if (patientEncounterItemServiceResponse.hasErrors()) { return ok(index.render(currentUserSession, patientEncounterItemServiceResponse.getErrors().get(""), 0)); } PatientEncounterItem patientEncounterItem = patientEncounterItemServiceResponse.getResponseObject(); //check for encounter closed if (patientEncounterItem.getIsClosed()) { return ok(index.render(currentUserSession, "That patient's encounter has been closed.", 0)); } //ensure prescriptions exist for that patient ServiceResponse<List<PrescriptionItem>> prescriptionItemsResponse = searchService.retrieveUnreplacedPrescriptionItems(patientEncounterItem.getId(), currentUserSession.getTripId()); if (prescriptionItemsResponse.hasErrors()) { throw new RuntimeException(); } else if (prescriptionItemsResponse.getResponseObject().size() < 1) { return ok(index.render(currentUserSession, "No prescriptions found for that patient", 0)); } return redirect(routes.PharmaciesController.editGet(patientId)); } public Result editGet(int patientId) { CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession(); EditViewModelGet viewModelGet = new EditViewModelGet(); String message; // Get settings ServiceResponse<SettingItem> response = searchService.retrieveSystemSettings(); if (response.hasErrors()) { throw new RuntimeException(); } viewModelGet.setSettings(response.getResponseObject()); //Get Patient ServiceResponse<PatientItem> patientItemServiceResponse = searchService.retrievePatientItemByPatientId(patientId); if (patientItemServiceResponse.hasErrors()) { message = patientItemServiceResponse.getErrors().get(""); return ok(index.render(currentUserSession, message, 0)); } PatientItem patient = patientItemServiceResponse.getResponseObject(); viewModelGet.setPatient(patient); //get the patient encounter item ServiceResponse<PatientEncounterItem> patientEncounterItemServiceResponse = searchService.retrieveRecentPatientEncounterItemByPatientId(patient.getId()); if (patientEncounterItemServiceResponse.hasErrors()) { message = patientEncounterItemServiceResponse.getErrors().get(""); return ok(index.render(currentUserSession, message, 0)); } PatientEncounterItem patientEncounterItem = patientEncounterItemServiceResponse.getResponseObject(); //check for encounter closed if (patientEncounterItem.getIsClosed()) { return ok(index.render(currentUserSession, "That patient's encounter has been closed.", 0)); } viewModelGet.setPatientEncounterItem(patientEncounterItem); //find patient prescriptions, they do have to exist ServiceResponse<List<PrescriptionItem>> prescriptionItemServiceResponse = searchService.retrieveUnreplacedPrescriptionItems(patientEncounterItem.getId(), currentUserSession.getTripId()); if (prescriptionItemServiceResponse.hasErrors()) { throw new RuntimeException(); } else if (prescriptionItemServiceResponse.getResponseObject().size() < 1) { return ok(index.render(currentUserSession, "No prescriptions found for that patient", 0)); } viewModelGet.setPrescriptions(prescriptionItemServiceResponse.getResponseObject()); // get inventory for prescriptions //get MedicationAdministrationItems ServiceResponse<List<MedicationAdministrationItem>> medicationAdministrationItemServiceResponse = medicationService.retrieveAvailableMedicationAdministrations(); if (medicationAdministrationItemServiceResponse.hasErrors()) { throw new RuntimeException(); } viewModelGet.setMedicationAdministrationItems(medicationAdministrationItemServiceResponse.getResponseObject()); //find patient problems, they do not have to exist. ServiceResponse<List<ProblemItem>> problemItemServiceResponse = encounterService.retrieveProblemItems(patientEncounterItem.getId()); if (problemItemServiceResponse.hasErrors()) { throw new RuntimeException(); } else { if (problemItemServiceResponse.getResponseObject().size() > 0) { viewModelGet.setProblems(problemItemServiceResponse.getResponseObject()); } } return ok(edit.render(currentUserSession, viewModelGet, false)); } public Result editPost(int id) { CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession(); // If form errors exist final Form<EditViewModelPost> populatedViewModelPostForm = formFactory.form(EditViewModelPost.class); EditViewModelPost createViewModelPost = populatedViewModelPostForm.bindFromRequest().get(); // @TODO -- Do validation on the counseled flag //get patient encounter ServiceResponse<PatientEncounterItem> patientEncounterItemServiceResponse = searchService.retrieveRecentPatientEncounterItemByPatientId(id); if (patientEncounterItemServiceResponse.hasErrors()) { throw new RuntimeException(); } PatientEncounterItem patientEncounterItem = patientEncounterItemServiceResponse.getResponseObject(); //get patient ServiceResponse<PatientItem> patientItemServiceResponse = searchService.retrievePatientItemByPatientId(patientEncounterItem.getPatientItem().getId()); if (patientItemServiceResponse.hasErrors()) { throw new RuntimeException(); } PatientItem patientItem = patientItemServiceResponse.getResponseObject(); //assume the patient was not counseled, set to true if they were. boolean isCounseled = false; if (createViewModelPost.getDisclaimer() == 1){ isCounseled = true; } // Map<id of the new prescription, id of the old prescription> Map<Integer, Integer> prescriptionsToReplace = new HashMap<>(); // Map<id, isCounseled> Map<Integer, Boolean> prescriptionsToDispense = new HashMap<>(); for(PrescriptionItem script : createViewModelPost.getPrescriptions()) { if (StringUtils.isNotNullOrWhiteSpace(script.getMedicationName())) { //The POST data sends -1 if an administration ID is not set. Null is more appropriate for the //service layer if (script.getAdministrationID() == -1) script.setAdministrationID(null); if (script.getMedicationID() != null){ //the medication has already been entered into the medications table (through admin inventory?) ServiceResponse<PrescriptionItem> createPrescriptionResponse = medicationService.createPrescription( script.getMedicationID(), script.getAdministrationID(), patientEncounterItem.getId(), currentUserSession.getId(), script.getAmountWithNull(), null); PrescriptionItem newPrescriptionItem = createPrescriptionResponse.getResponseObject(); //mark the prescription for replacing prescriptionsToReplace.put(newPrescriptionItem.getId(), script.getId()); }else{ //the medication has not already been entered into the medications table ServiceResponse<PrescriptionItem> createPrescriptionResponse = medicationService.createPrescriptionWithNewMedication( script.getMedicationName(), script.getAdministrationID(), patientEncounterItem.getId(), currentUserSession.getId(), script.getAmountWithNull(), null); PrescriptionItem newPrescriptionItem = createPrescriptionResponse.getResponseObject(); //mark the prescription for replacing prescriptionsToReplace.put(newPrescriptionItem.getId(), script.getId()); } } else { // mark the prescription for dispensing prescriptionsToDispense.put(script.getId(), isCounseled); } } // replace the prescriptions! (but do not dispense them) if (prescriptionsToReplace.size() > 0){ ServiceResponse<List<PrescriptionItem>> replacePrescriptionsServiceResponse = medicationService.replacePrescriptions(prescriptionsToReplace); if (replacePrescriptionsServiceResponse.hasErrors()) { throw new RuntimeException(); } else { for (PrescriptionItem prescriptionItem : replacePrescriptionsServiceResponse.getResponseObject()) { prescriptionsToDispense.put(prescriptionItem.getId(), prescriptionItem.getCounseled()); } } } // dispense the prescriptions! then inventory them! if (prescriptionsToDispense.size() > 0) { //dispense! ServiceResponse<List<PrescriptionItem>> dispensePrescriptionsServiceResponse = medicationService.dispensePrescriptions(prescriptionsToDispense); if (dispensePrescriptionsServiceResponse.hasErrors()) { throw new RuntimeException(); } else if( currentUserSession.getTripId() != null ) { //inventory -- user must be assigned to a trip for (PrescriptionItem prescriptionItem : dispensePrescriptionsServiceResponse.getResponseObject()) { ServiceResponse<MedicationItem> inventoryServiceResponse = inventoryService.subtractFromQuantityCurrent(prescriptionItem.getMedicationID(), currentUserSession.getTripId(), prescriptionItem.getAmount()); if (inventoryServiceResponse.hasErrors()){ throw new RuntimeException(); } } } } //check the patient in! encounterService.checkPatientInToPharmacy(patientEncounterItem.getId(), currentUserSession.getId()); String message = "Patient information for " + patientItem.getFirstName() + " " + patientItem.getLastName() + " (id: " + patientItem.getId() + ") was saved successfully."; return ok(index.render(currentUserSession, message, 0)); } }