From b03e0ded26cea268fe4ea1f3fe12aec107849c88 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:18:31 +0300 Subject: [PATCH 01/16] (Enhancement) Optimize patient dashboard loading by implementing pagination for observations --- .../web/controller/PortletController.java | 295 +++++++++++------- 1 file changed, 188 insertions(+), 107 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 959e523c..28505ace 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -11,12 +11,14 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.Collections; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -39,6 +41,7 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.legacyui.GeneralUtils; +import org.openmrs.util.OpenmrsConstants; import org.openmrs.util.PrivilegeConstants; import org.openmrs.web.WebConstants; import org.springframework.util.StringUtils; @@ -49,6 +52,8 @@ public class PortletController implements Controller { protected Log log = LogFactory.getLog(this.getClass()); + private static final int DEFAULT_PAGE_SIZE = 50; + /** * This method produces a model containing the following mappings: * @@ -97,11 +102,11 @@ public class PortletController implements Controller { */ @SuppressWarnings("unchecked") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException { - + IOException { + AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); - + // find the portlet that was identified in the openmrs:portlet taglib Object uri = request.getAttribute("javax.servlet.include.servlet_path"); String portletPath = ""; @@ -112,8 +117,8 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons String lastRequestId = (String) session.getAttribute(WebConstants.OPENMRS_PORTLET_LAST_REQ_ID); if (uniqueRequestId.equals(lastRequestId)) { model = (Map) session.getAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL); - - // remove cached parameters + + // remove cached parameters List parameterKeys = (List) model.get("parameterKeys"); if (parameterKeys != null) { for (String key : parameterKeys) { @@ -128,26 +133,27 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons session.setAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL, model); } } - + if (uri != null) { long timeAtStart = System.currentTimeMillis(); portletPath = uri.toString(); - + // Allowable extensions are '' (no extension) and '.portlet' if (portletPath.endsWith("portlet")) { portletPath = portletPath.replace(".portlet", ""); } else if (portletPath.endsWith("jsp")) { throw new ServletException( - "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); + "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); } - + log.debug("Loading portlet: " + portletPath); - + String id = (String) request.getAttribute("org.openmrs.portlet.id"); String size = (String) request.getAttribute("org.openmrs.portlet.size"); Map params = (Map) request.getAttribute("org.openmrs.portlet.parameters"); - Map moreParams = (Map) request.getAttribute("org.openmrs.portlet.parameterMap"); - + Map moreParams = (Map) request + .getAttribute("org.openmrs.portlet.parameterMap"); + model.put("now", new Date()); model.put("id", id); model.put("size", size); @@ -160,14 +166,15 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons parameterKeys.addAll(moreParams.keySet()); } model.put("parameterKeys", parameterKeys); // so we can clean these up in the next request - - // if there's an authenticated user, put them, and their patient set, in the model + + // if there's an authenticated user, put them, and their patient set, in the + // model if (Context.getAuthenticatedUser() != null) { model.put("authenticatedUser", Context.getAuthenticatedUser()); } - + Integer personId = null; - + // if a patient id is available, put patient data documented above in the model Object o = request.getAttribute("org.openmrs.portlet.patientId"); if (o != null) { @@ -180,88 +187,87 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (p.isDead()) { patientVariation = "Dead"; } - + // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { model.put("patientEncounters", Context.getEncounterService().getEncountersByPatient(p)); } - + // add visits if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_VISITS)) { - model.put("person", p); - PortletControllerUtil.addFormToEditAndViewUrlMaps(model); - model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); - model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); + // Check if visits are enabled in the system + String enableVisits = as.getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_ENABLE_VISITS, + "true"); + if (Boolean.valueOf(enableVisits)) { + model.put("person", p); + PortletControllerUtil.addFormToEditAndViewUrlMaps(model); + model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); + model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); + } } - + if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { - List patientObs = Context.getObsService().getObservationsByPerson(p); - model.put("patientObs", patientObs); + // Get pagination parameters + Integer page = getPageParameter(request); + Integer pageSize = getPageSizeParameter(request, as); + + // First, only fetch the specific concepts we need for BMI calculation + String weightString = as.getGlobalProperty("concept.weight"); + String heightString = as.getGlobalProperty("concept.height"); + + ConceptNumeric weightConcept = null; + ConceptNumeric heightConcept = null; + + if (StringUtils.hasLength(weightString)) { + weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + } + if (StringUtils.hasLength(heightString)) { + heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); + } + + // Get latest weight and height observations directly Obs latestWeight = null; Obs latestHeight = null; - String bmiAsString = "?"; - try { - String weightString = as.getGlobalProperty("concept.weight"); - ConceptNumeric weightConcept = null; - if (StringUtils.hasLength(weightString)) { - weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); - } - String heightString = as.getGlobalProperty("concept.height"); - ConceptNumeric heightConcept = null; - if (StringUtils.hasLength(heightString)) { - heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); - } - for (Obs obs : patientObs) { - if (obs.getConcept().equals(weightConcept)) { - if (latestWeight == null - || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { - latestWeight = obs; - } - } else if (obs.getConcept().equals(heightConcept) - && (latestHeight == null || obs.getObsDatetime().compareTo( - latestHeight.getObsDatetime()) > 0)) { - latestHeight = obs; - } - } - if (latestWeight != null) { - model.put("patientWeight", latestWeight); - } - if (latestHeight != null) { - model.put("patientHeight", latestHeight); - } - if (latestWeight != null && latestHeight != null) { - double weightInKg; - double heightInM; - if (weightConcept.getUnits().equalsIgnoreCase("kg")) { - weightInKg = latestWeight.getValueNumeric(); - } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { - weightInKg = latestWeight.getValueNumeric() * 0.45359237; - } else { - throw new IllegalArgumentException("Can't handle units of weight concept: " - + weightConcept.getUnits()); - } - if (heightConcept.getUnits().equalsIgnoreCase("cm")) { - heightInM = latestHeight.getValueNumeric() / 100; - } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { - heightInM = latestHeight.getValueNumeric(); - } else if (heightConcept.getUnits().equalsIgnoreCase("in")) { - heightInM = latestHeight.getValueNumeric() * 0.0254; - } else { - throw new IllegalArgumentException("Can't handle units of height concept: " - + heightConcept.getUnits()); - } - double bmi = weightInKg / (heightInM * heightInM); - model.put("patientBmi", bmi); - String temp = "" + bmi; - bmiAsString = temp.substring(0, temp.indexOf('.') + 2); + + if (weightConcept != null) { + List weightObs = Context.getObsService().getObservationsByPersonAndConcept(p, + weightConcept); + if (!weightObs.isEmpty()) { + latestWeight = Collections.max(weightObs, Comparator.comparing(Obs::getObsDatetime)); } } - catch (Exception ex) { - if (latestWeight != null && latestHeight != null) { - log.error("Failed to calculate BMI even though a weight and height were found", ex); + + if (heightConcept != null) { + List heightObs = Context.getObsService().getObservationsByPersonAndConcept(p, + heightConcept); + if (!heightObs.isEmpty()) { + latestHeight = Collections.max(heightObs, Comparator.comparing(Obs::getObsDatetime)); } } + + // Calculate BMI if we have both measurements + String bmiAsString = calculateBMI(latestWeight, latestHeight, weightConcept, heightConcept); + + // Get paginated observations + // Get all observations + List allObs = Context.getObsService().getObservationsByPerson(p); + + // Manual pagination + int startIndex = page * pageSize; + int endIndex = Math.min(startIndex + pageSize, allObs.size()); + List paginatedObs = allObs.subList(startIndex, endIndex); + + // Add counts to model + model.put("totalObsCount", allObs.size()); + + // Add pagination metadata to the model + model.put("currentPage", page); + model.put("pageSize", pageSize); + model.put("patientObs", paginatedObs); + model.put("patientWeight", latestWeight); + model.put("patientHeight", latestHeight); model.put("patientBmiAsString", bmiAsString); + } else { model.put("patientObs", new HashSet()); } @@ -278,7 +284,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept reasonForExitConcept = cs.getConcept(reasonForExitConceptString); if (reasonForExitConcept != null) { List patientExitObs = Context.getObsService().getObservationsByPersonAndConcept(p, - reasonForExitConcept); + reasonForExitConcept); if (patientExitObs != null) { log.debug("Exit obs is size " + patientExitObs.size()); if (patientExitObs.size() == 1) { @@ -299,25 +305,27 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } } model.put("patientReasonForExit", reasonForExitObs); - + if (Context.hasPrivilege(PrivilegeConstants.GET_PROGRAMS) - && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { + && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { model.put("patientPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, false)); + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, + false)); model.put( - "patientCurrentPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), new Date(), - null, false)); + "patientCurrentPrograms", + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), + new Date(), + null, false)); } - + model.put("patientId", patientId); personId = p.getPatientId(); model.put("personId", personId); - + model.put("patientVariation", patientVariation); } } - + // if a person id is available, put person and relationships in the model if (personId == null) { o = request.getAttribute("org.openmrs.portlet.personId"); @@ -335,8 +343,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("person", p); } - - if (!model.containsKey("personRelationships") && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { + + if (!model.containsKey("personRelationships") + && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { List relationships = new ArrayList(); relationships.addAll(Context.getPersonService().getRelationshipsByPerson(p)); Map> relationshipsByType = new HashMap>(); @@ -348,13 +357,14 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } list.add(rel); } - + model.put("personRelationships", relationships); model.put("personRelationshipsByType", relationshipsByType); } } - - // if an encounter id is available, put "encounter" and "encounterObs" in the model + + // if an encounter id is available, put "encounter" and "encounterObs" in the + // model o = request.getAttribute("org.openmrs.portlet.encounterId"); if (o != null && !model.containsKey("encounterId")) { if (!model.containsKey("encounter") && Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { @@ -366,7 +376,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("encounterId", (Integer) o); } } - + // if a user id is available, put "user" in the model o = request.getAttribute("org.openmrs.portlet.userId"); if (o != null && !model.containsKey("user")) { @@ -376,7 +386,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("userId", (Integer) o); } - + // if a list of patient ids is available, make a patientset out of it o = request.getAttribute("org.openmrs.portlet.patientIds"); if (!StringUtils.isEmpty(o) && !model.containsKey("patientIds") && !model.containsKey("patientSet")) { @@ -384,9 +394,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientSet", ps); model.put("patientIds", (String) o); } - + o = model.get("conceptIds"); - + if (!StringUtils.isEmpty(o) && !model.containsKey("conceptMap")) { log.debug("Found conceptIds parameter: " + o); Map concepts = new HashMap(); @@ -399,22 +409,93 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept c = cs.getConcept(i); concepts.put(i, c); conceptsByStringIds.put(i.toString(), c); - } - catch (Exception ex) { + } catch (Exception ex) { log.error("Error during putting int i into concept c", ex); } } - + model.put("conceptMap", concepts); model.put("conceptMapByStringIds", conceptsByStringIds); } - + populateModel(request, model); log.debug(portletPath + " took " + (System.currentTimeMillis() - timeAtStart) + " ms"); } - + return new ModelAndView(portletPath, "model", model); + + } + + private Integer getPageParameter(HttpServletRequest request) { + try { + return Integer.parseInt(request.getParameter("page")); + } + catch (NumberFormatException e) { + return 0; + } + } + + private Integer getPageSizeParameter(HttpServletRequest request, AdministrationService as) { + try { + String pageSizeParam = request.getParameter("pageSize"); + if (pageSizeParam != null) { + return Integer.parseInt(pageSizeParam); + } + + // Try to get from global properties + String globalPageSize = as.getGlobalProperty("dashboard.defaultPageSize"); + if (globalPageSize != null) { + return Integer.parseInt(globalPageSize); + } + } + catch (NumberFormatException e) { + log.debug("Unable to parse page size parameter, using default", e); + } + return DEFAULT_PAGE_SIZE; + } + + private String calculateBMI(Obs latestWeight, Obs latestHeight, ConceptNumeric weightConcept, + ConceptNumeric heightConcept) { + if (latestWeight == null || latestHeight == null) { + return "?"; + } + try { + double weightInKg = convertWeight(latestWeight.getValueNumeric(), weightConcept.getUnits()); + double heightInM = convertHeight(latestHeight.getValueNumeric(), heightConcept.getUnits()); + + double bmi = weightInKg / (heightInM * heightInM); + String temp = String.valueOf(bmi); + return temp.substring(0, temp.indexOf('.') + 2); + } + catch (Exception ex) { + log.error("Failed to calculate BMI", ex); + return "?"; + } + } + + private double convertWeight(double value, String units) { + switch (units.toLowerCase()) { + case "kg": + return value; + case "lb": + return value * 0.45359237; + default: + throw new IllegalArgumentException("Unsupported weight units: " + units); + } + } + + private double convertHeight(double value, String units) { + switch (units.toLowerCase()) { + case "cm": + return value / 100; + case "m": + return value; + case "in": + return value * 0.0254; + default: + throw new IllegalArgumentException("Unsupported height units: " + units); + } } /** From a06309a771b95c6e0858f5bf1bba6d1d997fcdcd Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Thu, 14 Nov 2024 09:01:56 +0300 Subject: [PATCH 02/16] Refactor to focus on pagination --- .../web/controller/PortletController.java | 273 ++++++++---------- 1 file changed, 121 insertions(+), 152 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 28505ace..512161a0 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -11,14 +11,12 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.Collections; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -41,7 +39,6 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.legacyui.GeneralUtils; -import org.openmrs.util.OpenmrsConstants; import org.openmrs.util.PrivilegeConstants; import org.openmrs.web.WebConstants; import org.springframework.util.StringUtils; @@ -102,8 +99,8 @@ public class PortletController implements Controller { */ @SuppressWarnings("unchecked") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException { - + IOException { + AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); @@ -143,17 +140,16 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons portletPath = portletPath.replace(".portlet", ""); } else if (portletPath.endsWith("jsp")) { throw new ServletException( - "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); + "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); } - + log.debug("Loading portlet: " + portletPath); - + String id = (String) request.getAttribute("org.openmrs.portlet.id"); String size = (String) request.getAttribute("org.openmrs.portlet.size"); Map params = (Map) request.getAttribute("org.openmrs.portlet.parameters"); - Map moreParams = (Map) request - .getAttribute("org.openmrs.portlet.parameterMap"); - + Map moreParams = (Map) request.getAttribute("org.openmrs.portlet.parameterMap"); + model.put("now", new Date()); model.put("id", id); model.put("size", size); @@ -166,15 +162,15 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons parameterKeys.addAll(moreParams.keySet()); } model.put("parameterKeys", parameterKeys); // so we can clean these up in the next request - + // if there's an authenticated user, put them, and their patient set, in the // model if (Context.getAuthenticatedUser() != null) { model.put("authenticatedUser", Context.getAuthenticatedUser()); } - + Integer personId = null; - + // if a patient id is available, put patient data documented above in the model Object o = request.getAttribute("org.openmrs.portlet.patientId"); if (o != null) { @@ -187,87 +183,107 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (p.isDead()) { patientVariation = "Dead"; } - + // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { model.put("patientEncounters", Context.getEncounterService().getEncountersByPatient(p)); } - + // add visits if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_VISITS)) { - // Check if visits are enabled in the system - String enableVisits = as.getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_ENABLE_VISITS, - "true"); - if (Boolean.valueOf(enableVisits)) { - model.put("person", p); - PortletControllerUtil.addFormToEditAndViewUrlMaps(model); - model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); - model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); - } + model.put("person", p); + PortletControllerUtil.addFormToEditAndViewUrlMaps(model); + model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); + model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); } - + if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { // Get pagination parameters Integer page = getPageParameter(request); Integer pageSize = getPageSizeParameter(request, as); - - // First, only fetch the specific concepts we need for BMI calculation - String weightString = as.getGlobalProperty("concept.weight"); - String heightString = as.getGlobalProperty("concept.height"); - - ConceptNumeric weightConcept = null; - ConceptNumeric heightConcept = null; - - if (StringUtils.hasLength(weightString)) { - weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); - } - if (StringUtils.hasLength(heightString)) { - heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); - } - - // Get latest weight and height observations directly - Obs latestWeight = null; - Obs latestHeight = null; - - if (weightConcept != null) { - List weightObs = Context.getObsService().getObservationsByPersonAndConcept(p, - weightConcept); - if (!weightObs.isEmpty()) { - latestWeight = Collections.max(weightObs, Comparator.comparing(Obs::getObsDatetime)); - } - } - - if (heightConcept != null) { - List heightObs = Context.getObsService().getObservationsByPersonAndConcept(p, - heightConcept); - if (!heightObs.isEmpty()) { - latestHeight = Collections.max(heightObs, Comparator.comparing(Obs::getObsDatetime)); - } - } - - // Calculate BMI if we have both measurements - String bmiAsString = calculateBMI(latestWeight, latestHeight, weightConcept, heightConcept); - - // Get paginated observations + // Get all observations List allObs = Context.getObsService().getObservationsByPerson(p); - + // Manual pagination int startIndex = page * pageSize; int endIndex = Math.min(startIndex + pageSize, allObs.size()); List paginatedObs = allObs.subList(startIndex, endIndex); - - // Add counts to model - model.put("totalObsCount", allObs.size()); - + // Add pagination metadata to the model model.put("currentPage", page); model.put("pageSize", pageSize); + model.put("totalObsCount", allObs.size()); model.put("patientObs", paginatedObs); - model.put("patientWeight", latestWeight); - model.put("patientHeight", latestHeight); + + Obs latestWeight = null; + Obs latestHeight = null; + String bmiAsString = "?"; + try { + String weightString = as.getGlobalProperty("concept.weight"); + ConceptNumeric weightConcept = null; + if (StringUtils.hasLength(weightString)) { + weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + } + String heightString = as.getGlobalProperty("concept.height"); + ConceptNumeric heightConcept = null; + if (StringUtils.hasLength(heightString)) { + heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); + } + + // Use allObs for weight/height calculation since we need all records to find + // the latest + for (Obs obs : allObs) { + if (obs.getConcept().equals(weightConcept)) { + if (latestWeight == null + || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { + latestWeight = obs; + } + } else if (obs.getConcept().equals(heightConcept) + && (latestHeight == null || obs.getObsDatetime().compareTo( + latestHeight.getObsDatetime()) > 0)) { + latestHeight = obs; + } + } + if (latestWeight != null) { + model.put("patientWeight", latestWeight); + } + if (latestHeight != null) { + model.put("patientHeight", latestHeight); + } + if (latestWeight != null && latestHeight != null) { + double weightInKg; + double heightInM; + if (weightConcept.getUnits().equalsIgnoreCase("kg")) { + weightInKg = latestWeight.getValueNumeric(); + } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { + weightInKg = latestWeight.getValueNumeric() * 0.45359237; + } else { + throw new IllegalArgumentException("Can't handle units of weight concept: " + + weightConcept.getUnits()); + } + if (heightConcept.getUnits().equalsIgnoreCase("cm")) { + heightInM = latestHeight.getValueNumeric() / 100; + } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { + heightInM = latestHeight.getValueNumeric(); + } else if (heightConcept.getUnits().equalsIgnoreCase("in")) { + heightInM = latestHeight.getValueNumeric() * 0.0254; + } else { + throw new IllegalArgumentException("Can't handle units of height concept: " + + heightConcept.getUnits()); + } + double bmi = weightInKg / (heightInM * heightInM); + model.put("patientBmi", bmi); + String temp = "" + bmi; + bmiAsString = temp.substring(0, temp.indexOf('.') + 2); + } + } + catch (Exception ex) { + if (latestWeight != null && latestHeight != null) { + log.error("Failed to calculate BMI even though a weight and height were found", ex); + } + } model.put("patientBmiAsString", bmiAsString); - } else { model.put("patientObs", new HashSet()); } @@ -284,7 +300,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept reasonForExitConcept = cs.getConcept(reasonForExitConceptString); if (reasonForExitConcept != null) { List patientExitObs = Context.getObsService().getObservationsByPersonAndConcept(p, - reasonForExitConcept); + reasonForExitConcept); if (patientExitObs != null) { log.debug("Exit obs is size " + patientExitObs.size()); if (patientExitObs.size() == 1) { @@ -305,27 +321,25 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } } model.put("patientReasonForExit", reasonForExitObs); - + if (Context.hasPrivilege(PrivilegeConstants.GET_PROGRAMS) - && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { + && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { model.put("patientPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, - false)); + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, false)); model.put( - "patientCurrentPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), - new Date(), - null, false)); + "patientCurrentPrograms", + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), new Date(), + null, false)); } - + model.put("patientId", patientId); personId = p.getPatientId(); model.put("personId", personId); - + model.put("patientVariation", patientVariation); } } - + // if a person id is available, put person and relationships in the model if (personId == null) { o = request.getAttribute("org.openmrs.portlet.personId"); @@ -343,9 +357,8 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("person", p); } - - if (!model.containsKey("personRelationships") - && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { + + if (!model.containsKey("personRelationships") && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { List relationships = new ArrayList(); relationships.addAll(Context.getPersonService().getRelationshipsByPerson(p)); Map> relationshipsByType = new HashMap>(); @@ -357,12 +370,12 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } list.add(rel); } - + model.put("personRelationships", relationships); model.put("personRelationshipsByType", relationshipsByType); } } - + // if an encounter id is available, put "encounter" and "encounterObs" in the // model o = request.getAttribute("org.openmrs.portlet.encounterId"); @@ -376,7 +389,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("encounterId", (Integer) o); } } - + // if a user id is available, put "user" in the model o = request.getAttribute("org.openmrs.portlet.userId"); if (o != null && !model.containsKey("user")) { @@ -386,7 +399,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("userId", (Integer) o); } - + // if a list of patient ids is available, make a patientset out of it o = request.getAttribute("org.openmrs.portlet.patientIds"); if (!StringUtils.isEmpty(o) && !model.containsKey("patientIds") && !model.containsKey("patientSet")) { @@ -394,9 +407,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientSet", ps); model.put("patientIds", (String) o); } - + o = model.get("conceptIds"); - + if (!StringUtils.isEmpty(o) && !model.containsKey("conceptMap")) { log.debug("Found conceptIds parameter: " + o); Map concepts = new HashMap(); @@ -409,21 +422,30 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept c = cs.getConcept(i); concepts.put(i, c); conceptsByStringIds.put(i.toString(), c); - } catch (Exception ex) { + } + catch (Exception ex) { log.error("Error during putting int i into concept c", ex); } } - + model.put("conceptMap", concepts); model.put("conceptMapByStringIds", conceptsByStringIds); } - + populateModel(request, model); log.debug(portletPath + " took " + (System.currentTimeMillis() - timeAtStart) + " ms"); } - + return new ModelAndView(portletPath, "model", model); - + + } + + /** + * Subclasses should override this to put more data into the model. This will be called AFTER + * handleRequest has put mappings in the model as described in its javadoc. Note that context + * could be null when this method is called. + */ + protected void populateModel(HttpServletRequest request, Map model) { } private Integer getPageParameter(HttpServletRequest request) { @@ -442,7 +464,6 @@ private Integer getPageSizeParameter(HttpServletRequest request, AdministrationS return Integer.parseInt(pageSizeParam); } - // Try to get from global properties String globalPageSize = as.getGlobalProperty("dashboard.defaultPageSize"); if (globalPageSize != null) { return Integer.parseInt(globalPageSize); @@ -454,56 +475,4 @@ private Integer getPageSizeParameter(HttpServletRequest request, AdministrationS return DEFAULT_PAGE_SIZE; } - private String calculateBMI(Obs latestWeight, Obs latestHeight, ConceptNumeric weightConcept, - ConceptNumeric heightConcept) { - if (latestWeight == null || latestHeight == null) { - return "?"; - } - - try { - double weightInKg = convertWeight(latestWeight.getValueNumeric(), weightConcept.getUnits()); - double heightInM = convertHeight(latestHeight.getValueNumeric(), heightConcept.getUnits()); - - double bmi = weightInKg / (heightInM * heightInM); - String temp = String.valueOf(bmi); - return temp.substring(0, temp.indexOf('.') + 2); - } - catch (Exception ex) { - log.error("Failed to calculate BMI", ex); - return "?"; - } - } - - private double convertWeight(double value, String units) { - switch (units.toLowerCase()) { - case "kg": - return value; - case "lb": - return value * 0.45359237; - default: - throw new IllegalArgumentException("Unsupported weight units: " + units); - } - } - - private double convertHeight(double value, String units) { - switch (units.toLowerCase()) { - case "cm": - return value / 100; - case "m": - return value; - case "in": - return value * 0.0254; - default: - throw new IllegalArgumentException("Unsupported height units: " + units); - } - } - - /** - * Subclasses should override this to put more data into the model. This will be called AFTER - * handleRequest has put mappings in the model as described in its javadoc. Note that context - * could be null when this method is called. - */ - protected void populateModel(HttpServletRequest request, Map model) { - } - } From ba7a0fcf829bdda22d113538c91b331c8808c6a6 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 29 Nov 2024 08:23:31 +0300 Subject: [PATCH 03/16] DB-level pagination to only load in memory obs for current page --- .../web/controller/PortletController.java | 85 ++++++++++++------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 512161a0..1062a5c9 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -29,6 +30,7 @@ import org.openmrs.Concept; import org.openmrs.ConceptNumeric; import org.openmrs.Encounter; +import org.openmrs.Location; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.Person; @@ -39,6 +41,7 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.legacyui.GeneralUtils; +import org.openmrs.util.OpenmrsConstants.PERSON_TYPE; import org.openmrs.util.PrivilegeConstants; import org.openmrs.web.WebConstants; import org.springframework.util.StringUtils; @@ -103,18 +106,19 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); - + // find the portlet that was identified in the openmrs:portlet taglib Object uri = request.getAttribute("javax.servlet.include.servlet_path"); String portletPath = ""; Map model = null; + { HttpSession session = request.getSession(); String uniqueRequestId = (String) request.getAttribute(WebConstants.INIT_REQ_UNIQUE_ID); String lastRequestId = (String) session.getAttribute(WebConstants.OPENMRS_PORTLET_LAST_REQ_ID); if (uniqueRequestId.equals(lastRequestId)) { model = (Map) session.getAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL); - + // remove cached parameters List parameterKeys = (List) model.get("parameterKeys"); if (parameterKeys != null) { @@ -130,11 +134,11 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons session.setAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL, model); } } - + if (uri != null) { long timeAtStart = System.currentTimeMillis(); portletPath = uri.toString(); - + // Allowable extensions are '' (no extension) and '.portlet' if (portletPath.endsWith("portlet")) { portletPath = portletPath.replace(".portlet", ""); @@ -162,7 +166,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons parameterKeys.addAll(moreParams.keySet()); } model.put("parameterKeys", parameterKeys); // so we can clean these up in the next request - + // if there's an authenticated user, put them, and their patient set, in the // model if (Context.getAuthenticatedUser() != null) { @@ -202,18 +206,32 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Integer page = getPageParameter(request); Integer pageSize = getPageSizeParameter(request, as); - // Get all observations - List allObs = Context.getObsService().getObservationsByPerson(p); + Person person = (Person) p; + List persons = Collections.singletonList(person); - // Manual pagination - int startIndex = page * pageSize; - int endIndex = Math.min(startIndex + pageSize, allObs.size()); - List paginatedObs = allObs.subList(startIndex, endIndex); + // Setup parameters for database-level pagination + List encounters = null; + List questions = null; + List answers = null; + List personTypes = null; + List locations = null; + List sort = Collections.singletonList("obsDatetime desc"); + Integer obsGroupId = null; + Date fromDate = null; + Date toDate = null; + boolean includeVoided = false; + + // Get observations for the current page + List paginatedObs = Context.getObsService().getObservations(persons, encounters, questions, + answers, personTypes, locations, sort, null, obsGroupId, fromDate, toDate, includeVoided); + + // Get total count for pagination + Integer totalCount = Context.getObsService().getObservationCount(persons, encounters, questions, + answers, personTypes, locations, obsGroupId, fromDate, toDate, includeVoided); - // Add pagination metadata to the model model.put("currentPage", page); model.put("pageSize", pageSize); - model.put("totalObsCount", allObs.size()); + model.put("totalObsCount", totalCount); model.put("patientObs", paginatedObs); Obs latestWeight = null; @@ -231,27 +249,34 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); } - // Use allObs for weight/height calculation since we need all records to find - // the latest - for (Obs obs : allObs) { - if (obs.getConcept().equals(weightConcept)) { - if (latestWeight == null - || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { - latestWeight = obs; - } - } else if (obs.getConcept().equals(heightConcept) - && (latestHeight == null || obs.getObsDatetime().compareTo( - latestHeight.getObsDatetime()) > 0)) { - latestHeight = obs; + if (weightConcept != null) { + List weightQuestions = Collections.singletonList(weightConcept); + List weightSort = Collections.singletonList("obsDatetime desc"); + + List weightObs = Context.getObsService().getObservations(persons, null, + weightQuestions, null, null, null, weightSort, 1, null, null, null, false); + + if (!weightObs.isEmpty()) { + latestWeight = weightObs.get(0); } } - if (latestWeight != null) { - model.put("patientWeight", latestWeight); - } - if (latestHeight != null) { - model.put("patientHeight", latestHeight); + + if (heightConcept != null) { + List heightQuestions = Collections.singletonList(heightConcept); + List heightSort = Collections.singletonList("obsDatetime desc"); + + List heightObs = Context.getObsService().getObservations(persons, null, + heightQuestions, null, null, null, heightSort, 1, null, null, null, false); + + if (!heightObs.isEmpty()) { + latestHeight = heightObs.get(0); + } } + if (latestWeight != null && latestHeight != null) { + model.put("patientWeight", latestWeight); + model.put("patientHeight", latestHeight); + double weightInKg; double heightInM; if (weightConcept.getUnits().equalsIgnoreCase("kg")) { From fa01899f2da7025a633ccaa60c187809b2bc117a Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:01:18 +0300 Subject: [PATCH 04/16] Limit loaded obs to MostRecentN --- .../web/controller/PortletController.java | 45 +++++-------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 1062a5c9..a24b8898 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -41,6 +42,8 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.legacyui.GeneralUtils; +import org.openmrs.parameter.EncounterSearchCriteria; +import org.openmrs.parameter.EncounterSearchCriteriaBuilder; import org.openmrs.util.OpenmrsConstants.PERSON_TYPE; import org.openmrs.util.PrivilegeConstants; import org.openmrs.web.WebConstants; @@ -190,7 +193,10 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { - model.put("patientEncounters", Context.getEncounterService().getEncountersByPatient(p)); + model.put( + "patientEncounters", + Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), 0, 100, + false)); } // add visits if this user can view them @@ -202,36 +208,16 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { - // Get pagination parameters - Integer page = getPageParameter(request); Integer pageSize = getPageSizeParameter(request, as); Person person = (Person) p; List persons = Collections.singletonList(person); - // Setup parameters for database-level pagination - List encounters = null; - List questions = null; - List answers = null; - List personTypes = null; - List locations = null; - List sort = Collections.singletonList("obsDatetime desc"); - Integer obsGroupId = null; - Date fromDate = null; - Date toDate = null; - boolean includeVoided = false; - - // Get observations for the current page - List paginatedObs = Context.getObsService().getObservations(persons, encounters, questions, - answers, personTypes, locations, sort, null, obsGroupId, fromDate, toDate, includeVoided); - - // Get total count for pagination - Integer totalCount = Context.getObsService().getObservationCount(persons, encounters, questions, - answers, personTypes, locations, obsGroupId, fromDate, toDate, includeVoided); + List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, + null, Collections.singletonList("obsDatetime desc"), pageSize, + null, null, null, false); - model.put("currentPage", page); model.put("pageSize", pageSize); - model.put("totalObsCount", totalCount); model.put("patientObs", paginatedObs); Obs latestWeight = null; @@ -473,15 +459,6 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons protected void populateModel(HttpServletRequest request, Map model) { } - private Integer getPageParameter(HttpServletRequest request) { - try { - return Integer.parseInt(request.getParameter("page")); - } - catch (NumberFormatException e) { - return 0; - } - } - private Integer getPageSizeParameter(HttpServletRequest request, AdministrationService as) { try { String pageSizeParam = request.getParameter("pageSize"); @@ -489,7 +466,7 @@ private Integer getPageSizeParameter(HttpServletRequest request, AdministrationS return Integer.parseInt(pageSizeParam); } - String globalPageSize = as.getGlobalProperty("dashboard.defaultPageSize"); + String globalPageSize = as.getGlobalProperty("dashboard.encounters.maximumNumberToShow"); if (globalPageSize != null) { return Integer.parseInt(globalPageSize); } From e1c2f60f524595b3409a0ae515d5c9a54894139c Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:36:24 +0300 Subject: [PATCH 05/16] Remove hard coding and keep values dynamic based on GP set with default to 50 --- .../web/controller/PortletController.java | 218 +++++++++++------- 1 file changed, 136 insertions(+), 82 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index a24b8898..2aa7b2c0 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -52,11 +52,11 @@ import org.springframework.web.servlet.mvc.Controller; public class PortletController implements Controller { - + protected Log log = LogFactory.getLog(this.getClass()); - + private static final int DEFAULT_PAGE_SIZE = 50; - + /** * This method produces a model containing the following mappings: * @@ -105,23 +105,23 @@ public class PortletController implements Controller { */ @SuppressWarnings("unchecked") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException { - + IOException { + AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); - + // find the portlet that was identified in the openmrs:portlet taglib Object uri = request.getAttribute("javax.servlet.include.servlet_path"); String portletPath = ""; Map model = null; - + { HttpSession session = request.getSession(); String uniqueRequestId = (String) request.getAttribute(WebConstants.INIT_REQ_UNIQUE_ID); String lastRequestId = (String) session.getAttribute(WebConstants.OPENMRS_PORTLET_LAST_REQ_ID); if (uniqueRequestId.equals(lastRequestId)) { model = (Map) session.getAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL); - + // remove cached parameters List parameterKeys = (List) model.get("parameterKeys"); if (parameterKeys != null) { @@ -137,26 +137,27 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons session.setAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL, model); } } - + if (uri != null) { long timeAtStart = System.currentTimeMillis(); portletPath = uri.toString(); - + // Allowable extensions are '' (no extension) and '.portlet' if (portletPath.endsWith("portlet")) { portletPath = portletPath.replace(".portlet", ""); } else if (portletPath.endsWith("jsp")) { throw new ServletException( - "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); + "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); } - + log.debug("Loading portlet: " + portletPath); - + String id = (String) request.getAttribute("org.openmrs.portlet.id"); String size = (String) request.getAttribute("org.openmrs.portlet.size"); Map params = (Map) request.getAttribute("org.openmrs.portlet.parameters"); - Map moreParams = (Map) request.getAttribute("org.openmrs.portlet.parameterMap"); - + Map moreParams = (Map) request + .getAttribute("org.openmrs.portlet.parameterMap"); + model.put("now", new Date()); model.put("id", id); model.put("size", size); @@ -169,15 +170,15 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons parameterKeys.addAll(moreParams.keySet()); } model.put("parameterKeys", parameterKeys); // so we can clean these up in the next request - + // if there's an authenticated user, put them, and their patient set, in the // model if (Context.getAuthenticatedUser() != null) { model.put("authenticatedUser", Context.getAuthenticatedUser()); } - + Integer personId = null; - + // if a patient id is available, put patient data documented above in the model Object o = request.getAttribute("org.openmrs.portlet.patientId"); if (o != null) { @@ -190,15 +191,19 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (p.isDead()) { patientVariation = "Dead"; } - + // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { - model.put( - "patientEncounters", - Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), 0, 100, - false)); + Integer pageSize = getPageSizeParameter(request, as); + Integer page = getPageParameter(request); // This will return 0 by default + + model.put("patientEncounters", + Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), + page, // use the page parameter + pageSize, // use configured page size + false)); } - + // add visits if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_VISITS)) { model.put("person", p); @@ -206,73 +211,110 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); } - + if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { Integer pageSize = getPageSizeParameter(request, as); - + Person person = (Person) p; List persons = Collections.singletonList(person); - - List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, - null, Collections.singletonList("obsDatetime desc"), pageSize, - null, null, null, false); - + + // Get most recent observations using mostRecentN + List paginatedObs = Context.getObsService().getObservations(persons, + null, + null, + null, + null, + null, + Collections.singletonList("obsDatetime desc"), + pageSize, + null, + null, + null, + false); + model.put("pageSize", pageSize); model.put("patientObs", paginatedObs); - + + // Handle BMI calculation Obs latestWeight = null; Obs latestHeight = null; String bmiAsString = "?"; + try { String weightString = as.getGlobalProperty("concept.weight"); ConceptNumeric weightConcept = null; if (StringUtils.hasLength(weightString)) { - weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + weightConcept = cs + .getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); } + String heightString = as.getGlobalProperty("concept.height"); ConceptNumeric heightConcept = null; if (StringUtils.hasLength(heightString)) { - heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); + heightConcept = cs + .getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); } - + if (weightConcept != null) { List weightQuestions = Collections.singletonList(weightConcept); List weightSort = Collections.singletonList("obsDatetime desc"); - - List weightObs = Context.getObsService().getObservations(persons, null, - weightQuestions, null, null, null, weightSort, 1, null, null, null, false); - + + List weightObs = Context.getObsService().getObservations(persons, + null, + weightQuestions, + null, + null, + null, + weightSort, + 1, + null, + null, + null, + false); + if (!weightObs.isEmpty()) { latestWeight = weightObs.get(0); } } - + if (heightConcept != null) { List heightQuestions = Collections.singletonList(heightConcept); List heightSort = Collections.singletonList("obsDatetime desc"); - - List heightObs = Context.getObsService().getObservations(persons, null, - heightQuestions, null, null, null, heightSort, 1, null, null, null, false); - + + List heightObs = Context.getObsService().getObservations(persons, + null, + heightQuestions, + null, + null, + null, + heightSort, + 1, + null, + null, + null, + false); + if (!heightObs.isEmpty()) { latestHeight = heightObs.get(0); } } - + if (latestWeight != null && latestHeight != null) { model.put("patientWeight", latestWeight); model.put("patientHeight", latestHeight); - + double weightInKg; double heightInM; + if (weightConcept.getUnits().equalsIgnoreCase("kg")) { weightInKg = latestWeight.getValueNumeric(); } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { weightInKg = latestWeight.getValueNumeric() * 0.45359237; } else { throw new IllegalArgumentException("Can't handle units of weight concept: " - + weightConcept.getUnits()); + + weightConcept.getUnits()); } + if (heightConcept.getUnits().equalsIgnoreCase("cm")) { heightInM = latestHeight.getValueNumeric() / 100; } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { @@ -281,19 +323,20 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons heightInM = latestHeight.getValueNumeric() * 0.0254; } else { throw new IllegalArgumentException("Can't handle units of height concept: " - + heightConcept.getUnits()); + + heightConcept.getUnits()); } + double bmi = weightInKg / (heightInM * heightInM); model.put("patientBmi", bmi); String temp = "" + bmi; bmiAsString = temp.substring(0, temp.indexOf('.') + 2); } - } - catch (Exception ex) { + } catch (Exception ex) { if (latestWeight != null && latestHeight != null) { log.error("Failed to calculate BMI even though a weight and height were found", ex); } } + model.put("patientBmiAsString", bmiAsString); } else { model.put("patientObs", new HashSet()); @@ -311,7 +354,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept reasonForExitConcept = cs.getConcept(reasonForExitConceptString); if (reasonForExitConcept != null) { List patientExitObs = Context.getObsService().getObservationsByPersonAndConcept(p, - reasonForExitConcept); + reasonForExitConcept); if (patientExitObs != null) { log.debug("Exit obs is size " + patientExitObs.size()); if (patientExitObs.size() == 1) { @@ -332,25 +375,27 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } } model.put("patientReasonForExit", reasonForExitObs); - + if (Context.hasPrivilege(PrivilegeConstants.GET_PROGRAMS) - && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { + && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { model.put("patientPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, false)); + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, + false)); model.put( - "patientCurrentPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), new Date(), - null, false)); + "patientCurrentPrograms", + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), + new Date(), + null, false)); } - + model.put("patientId", patientId); personId = p.getPatientId(); model.put("personId", personId); - + model.put("patientVariation", patientVariation); } } - + // if a person id is available, put person and relationships in the model if (personId == null) { o = request.getAttribute("org.openmrs.portlet.personId"); @@ -368,8 +413,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("person", p); } - - if (!model.containsKey("personRelationships") && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { + + if (!model.containsKey("personRelationships") + && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { List relationships = new ArrayList(); relationships.addAll(Context.getPersonService().getRelationshipsByPerson(p)); Map> relationshipsByType = new HashMap>(); @@ -381,12 +427,12 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } list.add(rel); } - + model.put("personRelationships", relationships); model.put("personRelationshipsByType", relationshipsByType); } } - + // if an encounter id is available, put "encounter" and "encounterObs" in the // model o = request.getAttribute("org.openmrs.portlet.encounterId"); @@ -400,7 +446,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("encounterId", (Integer) o); } } - + // if a user id is available, put "user" in the model o = request.getAttribute("org.openmrs.portlet.userId"); if (o != null && !model.containsKey("user")) { @@ -410,7 +456,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("userId", (Integer) o); } - + // if a list of patient ids is available, make a patientset out of it o = request.getAttribute("org.openmrs.portlet.patientIds"); if (!StringUtils.isEmpty(o) && !model.containsKey("patientIds") && !model.containsKey("patientSet")) { @@ -418,9 +464,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientSet", ps); model.put("patientIds", (String) o); } - + o = model.get("conceptIds"); - + if (!StringUtils.isEmpty(o) && !model.containsKey("conceptMap")) { log.debug("Found conceptIds parameter: " + o); Map concepts = new HashMap(); @@ -433,48 +479,56 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept c = cs.getConcept(i); concepts.put(i, c); conceptsByStringIds.put(i.toString(), c); - } - catch (Exception ex) { + } catch (Exception ex) { log.error("Error during putting int i into concept c", ex); } } - + model.put("conceptMap", concepts); model.put("conceptMapByStringIds", conceptsByStringIds); } - + populateModel(request, model); log.debug(portletPath + " took " + (System.currentTimeMillis() - timeAtStart) + " ms"); } - + return new ModelAndView(portletPath, "model", model); - + } - + /** - * Subclasses should override this to put more data into the model. This will be called AFTER - * handleRequest has put mappings in the model as described in its javadoc. Note that context + * Subclasses should override this to put more data into the model. This will be + * called AFTER + * handleRequest has put mappings in the model as described in its javadoc. Note + * that context * could be null when this method is called. */ protected void populateModel(HttpServletRequest request, Map model) { } - + + private Integer getPageParameter(HttpServletRequest request) { + try { + return Integer.parseInt(request.getParameter("page")); + } catch (NumberFormatException e) { + return 0; + } + } + private Integer getPageSizeParameter(HttpServletRequest request, AdministrationService as) { try { String pageSizeParam = request.getParameter("pageSize"); if (pageSizeParam != null) { return Integer.parseInt(pageSizeParam); } - + String globalPageSize = as.getGlobalProperty("dashboard.encounters.maximumNumberToShow"); if (globalPageSize != null) { return Integer.parseInt(globalPageSize); } - } - catch (NumberFormatException e) { + } catch (NumberFormatException e) { log.debug("Unable to parse page size parameter, using default", e); } return DEFAULT_PAGE_SIZE; } - + } From 94563777739682866645cbedb16209511e78b1d9 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:14:00 +0300 Subject: [PATCH 06/16] Change naming conventions --- .../web/controller/PortletController.java | 249 ++++++++---------- 1 file changed, 107 insertions(+), 142 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 2aa7b2c0..0f710e4d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -52,11 +52,11 @@ import org.springframework.web.servlet.mvc.Controller; public class PortletController implements Controller { - + protected Log log = LogFactory.getLog(this.getClass()); - + private static final int DEFAULT_PAGE_SIZE = 50; - + /** * This method produces a model containing the following mappings: * @@ -105,23 +105,23 @@ public class PortletController implements Controller { */ @SuppressWarnings("unchecked") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException { - + IOException { + AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); - + // find the portlet that was identified in the openmrs:portlet taglib Object uri = request.getAttribute("javax.servlet.include.servlet_path"); String portletPath = ""; Map model = null; - + { HttpSession session = request.getSession(); String uniqueRequestId = (String) request.getAttribute(WebConstants.INIT_REQ_UNIQUE_ID); String lastRequestId = (String) session.getAttribute(WebConstants.OPENMRS_PORTLET_LAST_REQ_ID); if (uniqueRequestId.equals(lastRequestId)) { model = (Map) session.getAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL); - + // remove cached parameters List parameterKeys = (List) model.get("parameterKeys"); if (parameterKeys != null) { @@ -137,27 +137,26 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons session.setAttribute(WebConstants.OPENMRS_PORTLET_CACHED_MODEL, model); } } - + if (uri != null) { long timeAtStart = System.currentTimeMillis(); portletPath = uri.toString(); - + // Allowable extensions are '' (no extension) and '.portlet' if (portletPath.endsWith("portlet")) { portletPath = portletPath.replace(".portlet", ""); } else if (portletPath.endsWith("jsp")) { throw new ServletException( - "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); + "Illegal extension used for portlet: '.jsp'. Allowable extensions are '' (no extension) and '.portlet'"); } - + log.debug("Loading portlet: " + portletPath); - + String id = (String) request.getAttribute("org.openmrs.portlet.id"); String size = (String) request.getAttribute("org.openmrs.portlet.size"); Map params = (Map) request.getAttribute("org.openmrs.portlet.parameters"); - Map moreParams = (Map) request - .getAttribute("org.openmrs.portlet.parameterMap"); - + Map moreParams = (Map) request.getAttribute("org.openmrs.portlet.parameterMap"); + model.put("now", new Date()); model.put("id", id); model.put("size", size); @@ -170,15 +169,15 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons parameterKeys.addAll(moreParams.keySet()); } model.put("parameterKeys", parameterKeys); // so we can clean these up in the next request - + // if there's an authenticated user, put them, and their patient set, in the // model if (Context.getAuthenticatedUser() != null) { model.put("authenticatedUser", Context.getAuthenticatedUser()); } - + Integer personId = null; - + // if a patient id is available, put patient data documented above in the model Object o = request.getAttribute("org.openmrs.portlet.patientId"); if (o != null) { @@ -191,19 +190,18 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (p.isDead()) { patientVariation = "Dead"; } - + // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { - Integer pageSize = getPageSizeParameter(request, as); - Integer page = getPageParameter(request); // This will return 0 by default - - model.put("patientEncounters", - Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), - page, // use the page parameter - pageSize, // use configured page size - false)); + Integer limit = getLimitParameter(request, as); + Integer startIndex = getStartIndexParameter(request); + + model.put( + "patientEncounters", + Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), + startIndex, limit, false)); } - + // add visits if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_VISITS)) { model.put("person", p); @@ -211,110 +209,78 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientVisits", Context.getVisitService().getVisitsByPatient(p)); model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); } - + if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { - Integer pageSize = getPageSizeParameter(request, as); - + Integer limit = getLimitParameter(request, as); + Person person = (Person) p; List persons = Collections.singletonList(person); - - // Get most recent observations using mostRecentN - List paginatedObs = Context.getObsService().getObservations(persons, - null, - null, - null, - null, - null, - Collections.singletonList("obsDatetime desc"), - pageSize, - null, - null, - null, - false); - - model.put("pageSize", pageSize); + + // Get most recent observations using limit parameter + List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, + null, Collections.singletonList("obsDatetime desc"), limit, null, null, null, false); + + model.put("limit", limit); model.put("patientObs", paginatedObs); - + // Handle BMI calculation Obs latestWeight = null; Obs latestHeight = null; String bmiAsString = "?"; - + try { String weightString = as.getGlobalProperty("concept.weight"); ConceptNumeric weightConcept = null; if (StringUtils.hasLength(weightString)) { - weightConcept = cs - .getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); } - + String heightString = as.getGlobalProperty("concept.height"); ConceptNumeric heightConcept = null; if (StringUtils.hasLength(heightString)) { - heightConcept = cs - .getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); + heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); } - + if (weightConcept != null) { List weightQuestions = Collections.singletonList(weightConcept); List weightSort = Collections.singletonList("obsDatetime desc"); - - List weightObs = Context.getObsService().getObservations(persons, - null, - weightQuestions, - null, - null, - null, - weightSort, - 1, - null, - null, - null, - false); - + + List weightObs = Context.getObsService().getObservations(persons, null, + weightQuestions, null, null, null, weightSort, 1, null, null, null, false); + if (!weightObs.isEmpty()) { latestWeight = weightObs.get(0); } } - + if (heightConcept != null) { List heightQuestions = Collections.singletonList(heightConcept); List heightSort = Collections.singletonList("obsDatetime desc"); - - List heightObs = Context.getObsService().getObservations(persons, - null, - heightQuestions, - null, - null, - null, - heightSort, - 1, - null, - null, - null, - false); - + + List heightObs = Context.getObsService().getObservations(persons, null, + heightQuestions, null, null, null, heightSort, 1, null, null, null, false); + if (!heightObs.isEmpty()) { latestHeight = heightObs.get(0); } } - + if (latestWeight != null && latestHeight != null) { model.put("patientWeight", latestWeight); model.put("patientHeight", latestHeight); - + double weightInKg; double heightInM; - + if (weightConcept.getUnits().equalsIgnoreCase("kg")) { weightInKg = latestWeight.getValueNumeric(); } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { weightInKg = latestWeight.getValueNumeric() * 0.45359237; } else { throw new IllegalArgumentException("Can't handle units of weight concept: " - + weightConcept.getUnits()); + + weightConcept.getUnits()); } - + if (heightConcept.getUnits().equalsIgnoreCase("cm")) { heightInM = latestHeight.getValueNumeric() / 100; } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { @@ -323,20 +289,21 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons heightInM = latestHeight.getValueNumeric() * 0.0254; } else { throw new IllegalArgumentException("Can't handle units of height concept: " - + heightConcept.getUnits()); + + heightConcept.getUnits()); } - + double bmi = weightInKg / (heightInM * heightInM); model.put("patientBmi", bmi); String temp = "" + bmi; bmiAsString = temp.substring(0, temp.indexOf('.') + 2); } - } catch (Exception ex) { + } + catch (Exception ex) { if (latestWeight != null && latestHeight != null) { log.error("Failed to calculate BMI even though a weight and height were found", ex); } } - + model.put("patientBmiAsString", bmiAsString); } else { model.put("patientObs", new HashSet()); @@ -354,7 +321,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept reasonForExitConcept = cs.getConcept(reasonForExitConceptString); if (reasonForExitConcept != null) { List patientExitObs = Context.getObsService().getObservationsByPersonAndConcept(p, - reasonForExitConcept); + reasonForExitConcept); if (patientExitObs != null) { log.debug("Exit obs is size " + patientExitObs.size()); if (patientExitObs.size() == 1) { @@ -375,27 +342,25 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } } model.put("patientReasonForExit", reasonForExitObs); - + if (Context.hasPrivilege(PrivilegeConstants.GET_PROGRAMS) - && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { + && Context.hasPrivilege(PrivilegeConstants.GET_PATIENT_PROGRAMS)) { model.put("patientPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, - false)); + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, null, null, null, false)); model.put( - "patientCurrentPrograms", - Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), - new Date(), - null, false)); + "patientCurrentPrograms", + Context.getProgramWorkflowService().getPatientPrograms(p, null, null, new Date(), new Date(), + null, false)); } - + model.put("patientId", patientId); personId = p.getPatientId(); model.put("personId", personId); - + model.put("patientVariation", patientVariation); } } - + // if a person id is available, put person and relationships in the model if (personId == null) { o = request.getAttribute("org.openmrs.portlet.personId"); @@ -413,9 +378,8 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("person", p); } - - if (!model.containsKey("personRelationships") - && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { + + if (!model.containsKey("personRelationships") && Context.hasPrivilege(PrivilegeConstants.GET_RELATIONSHIPS)) { List relationships = new ArrayList(); relationships.addAll(Context.getPersonService().getRelationshipsByPerson(p)); Map> relationshipsByType = new HashMap>(); @@ -427,12 +391,12 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } list.add(rel); } - + model.put("personRelationships", relationships); model.put("personRelationshipsByType", relationshipsByType); } } - + // if an encounter id is available, put "encounter" and "encounterObs" in the // model o = request.getAttribute("org.openmrs.portlet.encounterId"); @@ -446,7 +410,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("encounterId", (Integer) o); } } - + // if a user id is available, put "user" in the model o = request.getAttribute("org.openmrs.portlet.userId"); if (o != null && !model.containsKey("user")) { @@ -456,7 +420,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } model.put("userId", (Integer) o); } - + // if a list of patient ids is available, make a patientset out of it o = request.getAttribute("org.openmrs.portlet.patientIds"); if (!StringUtils.isEmpty(o) && !model.containsKey("patientIds") && !model.containsKey("patientSet")) { @@ -464,9 +428,9 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("patientSet", ps); model.put("patientIds", (String) o); } - + o = model.get("conceptIds"); - + if (!StringUtils.isEmpty(o) && !model.containsKey("conceptMap")) { log.debug("Found conceptIds parameter: " + o); Map concepts = new HashMap(); @@ -479,56 +443,57 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Concept c = cs.getConcept(i); concepts.put(i, c); conceptsByStringIds.put(i.toString(), c); - } catch (Exception ex) { + } + catch (Exception ex) { log.error("Error during putting int i into concept c", ex); } } - + model.put("conceptMap", concepts); model.put("conceptMapByStringIds", conceptsByStringIds); } - + populateModel(request, model); log.debug(portletPath + " took " + (System.currentTimeMillis() - timeAtStart) + " ms"); } - + return new ModelAndView(portletPath, "model", model); - + } - + /** - * Subclasses should override this to put more data into the model. This will be - * called AFTER - * handleRequest has put mappings in the model as described in its javadoc. Note - * that context + * Subclasses should override this to put more data into the model. This will be called AFTER + * handleRequest has put mappings in the model as described in its javadoc. Note that context * could be null when this method is called. */ protected void populateModel(HttpServletRequest request, Map model) { } - - private Integer getPageParameter(HttpServletRequest request) { + + private Integer getStartIndexParameter(HttpServletRequest request) { try { - return Integer.parseInt(request.getParameter("page")); - } catch (NumberFormatException e) { - return 0; + return Integer.parseInt(request.getParameter("startIndex")); + } + catch (NumberFormatException e) { + return 0; // Return first page if not specified } } - - private Integer getPageSizeParameter(HttpServletRequest request, AdministrationService as) { + + private Integer getLimitParameter(HttpServletRequest request, AdministrationService as) { try { - String pageSizeParam = request.getParameter("pageSize"); - if (pageSizeParam != null) { - return Integer.parseInt(pageSizeParam); + String limitParam = request.getParameter("limit"); + if (limitParam != null) { + return Integer.parseInt(limitParam); } - - String globalPageSize = as.getGlobalProperty("dashboard.encounters.maximumNumberToShow"); - if (globalPageSize != null) { - return Integer.parseInt(globalPageSize); + + String globalLimit = as.getGlobalProperty("dashboard.encounters.maximumNumberToShow"); + if (globalLimit != null) { + return Integer.parseInt(globalLimit); } - } catch (NumberFormatException e) { - log.debug("Unable to parse page size parameter, using default", e); + } + catch (NumberFormatException e) { + log.debug("Unable to parse limit parameter, using default", e); } return DEFAULT_PAGE_SIZE; } - + } From 98301a5afce0e3241e9caa47a2c0c17715505dd9 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:50:32 +0300 Subject: [PATCH 07/16] Create seperate GP for observations --- .../web/controller/PortletController.java | 14 +- omod/src/main/resources/config.xml | 301 +++++++++--------- 2 files changed, 159 insertions(+), 156 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 0f710e4d..7d826574 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -31,7 +30,6 @@ import org.openmrs.Concept; import org.openmrs.ConceptNumeric; import org.openmrs.Encounter; -import org.openmrs.Location; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.Person; @@ -42,9 +40,6 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.legacyui.GeneralUtils; -import org.openmrs.parameter.EncounterSearchCriteria; -import org.openmrs.parameter.EncounterSearchCriteriaBuilder; -import org.openmrs.util.OpenmrsConstants.PERSON_TYPE; import org.openmrs.util.PrivilegeConstants; import org.openmrs.web.WebConstants; import org.springframework.util.StringUtils; @@ -193,7 +188,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons // add encounters if this user can view them if (Context.hasPrivilege(PrivilegeConstants.GET_ENCOUNTERS)) { - Integer limit = getLimitParameter(request, as); + Integer limit = getLimitParameter(request, as, "dashboard.encounters.maximumNumberToShow"); Integer startIndex = getStartIndexParameter(request); model.put( @@ -211,7 +206,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { - Integer limit = getLimitParameter(request, as); + Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); Person person = (Person) p; List persons = Collections.singletonList(person); @@ -478,14 +473,13 @@ private Integer getStartIndexParameter(HttpServletRequest request) { } } - private Integer getLimitParameter(HttpServletRequest request, AdministrationService as) { + private Integer getLimitParameter(HttpServletRequest request, AdministrationService as, String globalPropertyKey) { try { String limitParam = request.getParameter("limit"); if (limitParam != null) { return Integer.parseInt(limitParam); } - - String globalLimit = as.getGlobalProperty("dashboard.encounters.maximumNumberToShow"); + String globalLimit = as.getGlobalProperty(globalPropertyKey); if (globalLimit != null) { return Integer.parseInt(globalLimit); } diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 4e78b785..f17ab243 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -26,72 +26,72 @@ ${openmrsPlatformVersion} - + ${project.parent.groupId}.${project.parent.artifactId}.LegacyUIActivator - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - + + + - + - - - + + + - + - - - - - - - + + + + + + + - + @@ -114,131 +114,131 @@ - + - - - - - - - - - - + + + + + + + + + + - + - - - + + + - + - - - - - - - + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - + - - + + - + - - - - + + + + - + - - - - - - - - - - + + + + + + + + + + - + - - - - + + + + - + - - + + - + - - - + + + - + - - - + + + - + - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + org.openmrs.web.servlet.QuickReportServlet - complexObsServlet - org.openmrs.web.servlet.ComplexObsServlet - - + complexObsServlet + org.openmrs.web.servlet.ComplexObsServlet + + sampleFlowsheetServlet org.openmrs.web.servlet.SampleFlowsheetServlet @@ -338,18 +338,18 @@ dwr-invoker org.openmrs.web.dwr.OpenmrsDWRServlet - + - dwrFilter - org.openmrs.web.dwr.DwrFilter + dwrFilter + org.openmrs.web.dwr.DwrFilter - dwrFilter - /dwr/* + dwrFilter + /dwr/* - dwrFilter - /ms/call/plaincall/* + dwrFilter + /ms/call/plaincall/* @@ -379,7 +379,16 @@ dashboard.formEntry.maximumNumberEncountersToShow - Allows one to limit the number of encounters shown on the form entry tab of the patient dashboard specifically + Allows one to limit the number of encounters shown on the form entry tab of the patient + dashboard specifically + + + + dashboard.observations.maximumNumberToShow + false + + Allows one to limit the number of observations shown on the patient dashboard + specifically. From 639a616e9be56a5b1b41891e486d133a4a4eb93a Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:00:54 +0300 Subject: [PATCH 08/16] Remove extra formatting --- omod/src/main/resources/config.xml | 338 ++++++++++++++--------------- 1 file changed, 169 insertions(+), 169 deletions(-) diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index f17ab243..508bee15 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -26,215 +26,215 @@ ${openmrsPlatformVersion} - + ${project.parent.groupId}.${project.parent.artifactId}.LegacyUIActivator - + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - + + + + + + + - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - + - - - - + + + + - + - - - - - - - - + + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - + - - - + + + - + - - - - - + + + + + - + - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - - + + + - + - - - - + + + + - + - - - - + + + + - + - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + @@ -323,8 +323,8 @@ org.openmrs.web.servlet.QuickReportServlet - complexObsServlet - org.openmrs.web.servlet.ComplexObsServlet + complexObsServlet + org.openmrs.web.servlet.ComplexObsServlet sampleFlowsheetServlet @@ -338,14 +338,14 @@ dwr-invoker org.openmrs.web.dwr.OpenmrsDWRServlet - + - dwrFilter - org.openmrs.web.dwr.DwrFilter + dwrFilter + org.openmrs.web.dwr.DwrFilter - dwrFilter - /dwr/* + dwrFilter + /dwr/* dwrFilter @@ -367,7 +367,7 @@ messages_es.properties - + legacyui.enableExitFromCare false From 3426cb90a802778cfbd2a639e302766b8513c73f Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:44:53 +0300 Subject: [PATCH 09/16] Remove extra formatting --- omod/src/main/resources/config.xml | 139 ++++++++++++++--------------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 508bee15..015d5e58 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -34,13 +34,13 @@ - + - + - + @@ -59,23 +59,23 @@ - + - + - + - - - - - + + + + + @@ -91,28 +91,28 @@ - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -130,14 +130,14 @@ - + - + @@ -148,7 +148,7 @@ - + @@ -162,13 +162,13 @@ - + - + @@ -187,58 +187,58 @@ - + - + - + - + - + - + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + org.openmrs.web.servlet.QuickReportServlet - complexObsServlet - org.openmrs.web.servlet.ComplexObsServlet - - + complexObsServlet + org.openmrs.web.servlet.ComplexObsServlet + + sampleFlowsheetServlet org.openmrs.web.servlet.SampleFlowsheetServlet @@ -348,8 +348,8 @@ /dwr/* - dwrFilter - /ms/call/plaincall/* + dwrFilter + /ms/call/plaincall/* @@ -367,7 +367,7 @@ messages_es.properties - + legacyui.enableExitFromCare false @@ -379,11 +379,10 @@ dashboard.formEntry.maximumNumberEncountersToShow - Allows one to limit the number of encounters shown on the form entry tab of the patient - dashboard specifically + Allows one to limit the number of encounters shown on the form entry tab of the patient dashboard specifically - + dashboard.observations.maximumNumberToShow false From 1bf5bea97bd1af6de08afc24f0f7bd3913b81cef Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:00:26 +0300 Subject: [PATCH 10/16] Remove false as default value --- omod/src/main/resources/config.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 015d5e58..b96f2e3a 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -384,7 +384,7 @@ dashboard.observations.maximumNumberToShow - false + Allows one to limit the number of observations shown on the patient dashboard specifically. @@ -392,4 +392,3 @@ - From 6bcaedada39840ba5a3587c04bc056b410419f9c Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:36:22 +0300 Subject: [PATCH 11/16] Add StartIndex to getObservation api --- .../java/org/openmrs/web/controller/PortletController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 7d826574..564bb105 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -207,13 +207,14 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); + Integer startIndex = getStartIndexParameter(request); Person person = (Person) p; List persons = Collections.singletonList(person); // Get most recent observations using limit parameter - List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, - null, Collections.singletonList("obsDatetime desc"), limit, null, null, null, false); + List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, null, + Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); model.put("limit", limit); model.put("patientObs", paginatedObs); From d7e586613ed570a9129a70a182b95e3c390b979e Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Sun, 8 Dec 2024 18:02:50 +0300 Subject: [PATCH 12/16] Add proper null checks using StringUtils.hasText(), update getEncounter signature --- .../web/controller/PortletController.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 564bb105..4c267e66 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -191,10 +191,8 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Integer limit = getLimitParameter(request, as, "dashboard.encounters.maximumNumberToShow"); Integer startIndex = getStartIndexParameter(request); - model.put( - "patientEncounters", - Context.getEncounterService().getEncounters(p.getPatientIdentifier().getIdentifier(), - startIndex, limit, false)); + model.put("patientEncounters", + Context.getEncounterService().getEncounters(null, p.getPatientId(), startIndex, limit, false)); } // add visits if this user can view them @@ -213,8 +211,8 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons List persons = Collections.singletonList(person); // Get most recent observations using limit parameter - List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, null, - Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); + List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, + null, Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); model.put("limit", limit); model.put("patientObs", paginatedObs); @@ -467,21 +465,26 @@ protected void populateModel(HttpServletRequest request, Map mod private Integer getStartIndexParameter(HttpServletRequest request) { try { - return Integer.parseInt(request.getParameter("startIndex")); + String startIndexParam = request.getParameter("startIndex"); + if (StringUtils.hasText(startIndexParam)) { + return Integer.parseInt(startIndexParam); + } } catch (NumberFormatException e) { - return 0; // Return first page if not specified + log.debug("Unable to parse startIndex parameter, using default", e); } + return 0; // Return first page if not specified or invalid } private Integer getLimitParameter(HttpServletRequest request, AdministrationService as, String globalPropertyKey) { try { String limitParam = request.getParameter("limit"); - if (limitParam != null) { + if (StringUtils.hasText(limitParam)) { return Integer.parseInt(limitParam); } + String globalLimit = as.getGlobalProperty(globalPropertyKey); - if (globalLimit != null) { + if (StringUtils.hasText(globalLimit)) { return Integer.parseInt(globalLimit); } } From a6b840c171ed7b7f4b5d0db4a6eaf5f7a7bb1320 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:35:55 +0300 Subject: [PATCH 13/16] Keep obs set for BMI calculations, remove unused limit param from model --- .../web/controller/PortletController.java | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 4c267e66..f373c72a 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -210,11 +210,14 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Person person = (Person) p; List persons = Collections.singletonList(person); - // Get most recent observations using limit parameter + // Get paginated observations List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, null, Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); - model.put("limit", limit); + // Get all observations for BMI calculation + List allObs = Context.getObsService().getObservations(persons, null, null, null, null, null, + null, null, null, null, null, false); + model.put("patientObs", paginatedObs); // Handle BMI calculation @@ -235,34 +238,28 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); } - if (weightConcept != null) { - List weightQuestions = Collections.singletonList(weightConcept); - List weightSort = Collections.singletonList("obsDatetime desc"); - - List weightObs = Context.getObsService().getObservations(persons, null, - weightQuestions, null, null, null, weightSort, 1, null, null, null, false); - - if (!weightObs.isEmpty()) { - latestWeight = weightObs.get(0); + // Find weight and height from all observations + for (Obs obs : allObs) { + if (obs.getConcept().equals(weightConcept)) { + if (latestWeight == null + || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { + latestWeight = obs; + } + } else if (obs.getConcept().equals(heightConcept) + && (latestHeight == null || obs.getObsDatetime().compareTo( + latestHeight.getObsDatetime()) > 0)) { + latestHeight = obs; } } - if (heightConcept != null) { - List heightQuestions = Collections.singletonList(heightConcept); - List heightSort = Collections.singletonList("obsDatetime desc"); - - List heightObs = Context.getObsService().getObservations(persons, null, - heightQuestions, null, null, null, heightSort, 1, null, null, null, false); - - if (!heightObs.isEmpty()) { - latestHeight = heightObs.get(0); - } + if (latestWeight != null) { + model.put("patientWeight", latestWeight); + } + if (latestHeight != null) { + model.put("patientHeight", latestHeight); } if (latestWeight != null && latestHeight != null) { - model.put("patientWeight", latestWeight); - model.put("patientHeight", latestHeight); - double weightInKg; double heightInM; From b763c927e3f6fa323c995a1da7548f7b83e0112f Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:09:09 +0300 Subject: [PATCH 14/16] Enhance obs to load latest weight and height --- .../web/controller/PortletController.java | 156 ++++++++++++++---- 1 file changed, 123 insertions(+), 33 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index f373c72a..d032370a 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -203,6 +203,108 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); } + // if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { + // Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); + // Integer startIndex = getStartIndexParameter(request); + + // Person person = (Person) p; + // List persons = Collections.singletonList(person); + + // // Get paginated observations + // String weightString = as.getGlobalProperty("concept.weight"); + // String heightString = as.getGlobalProperty("concept.height"); + // // List concepts = new ArrayList(); + // // concepts.add(GeneralUtils.getConcept(weightString)); + // List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, + // null, Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); + + // // Get all observations for BMI calculation + // List weightObs = Context.getObsService().getObservations(persons, null, Collections.singletonList(GeneralUtils.getConcept(weightString)), null, null, null, + // Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + + // List heightObs = Context.getObsService().getObservations(persons, null, Collections.singletonList(GeneralUtils.getConcept(heightString)), null, null, null, + // Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + + // model.put("patientObs", paginatedObs); + + // // Handle BMI calculation + // Obs latestWeight = weightObs.get(0); + // Obs latestHeight = heightObs.get(0); + // String bmiAsString = "?"; + + // try { + // ConceptNumeric weightConcept = null; + // if (StringUtils.hasLength(weightString)) { + // weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + // } + + // ConceptNumeric heightConcept = null; + // if (StringUtils.hasLength(heightString)) { + // heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); + // } + + // // Find weight and height from all observations + // // for (Obs obs : allObs) { + // // if (obs.getConcept().equals(weightConcept)) { + // // if (latestWeight == null + // // || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { + // // latestWeight = obs; + // // } + // // } else if (obs.getConcept().equals(heightConcept) + // // && (latestHeight == null || obs.getObsDatetime().compareTo( + // // latestHeight.getObsDatetime()) > 0)) { + // // latestHeight = obs; + // // } + // // } + + // if (latestWeight != null) { + // model.put("patientWeight", latestWeight); + // } + // if (latestHeight != null) { + // model.put("patientHeight", latestHeight); + // } + + // if (latestWeight != null && latestHeight != null) { + // double weightInKg; + // double heightInM; + + // if (weightConcept.getUnits().equalsIgnoreCase("kg")) { + // weightInKg = latestWeight.getValueNumeric(); + // } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { + // weightInKg = latestWeight.getValueNumeric() * 0.45359237; + // } else { + // throw new IllegalArgumentException("Can't handle units of weight concept: " + // + weightConcept.getUnits()); + // } + + // if (heightConcept.getUnits().equalsIgnoreCase("cm")) { + // heightInM = latestHeight.getValueNumeric() / 100; + // } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { + // heightInM = latestHeight.getValueNumeric(); + // } else if (heightConcept.getUnits().equalsIgnoreCase("in")) { + // heightInM = latestHeight.getValueNumeric() * 0.0254; + // } else { + // throw new IllegalArgumentException("Can't handle units of height concept: " + // + heightConcept.getUnits()); + // } + + // double bmi = weightInKg / (heightInM * heightInM); + // model.put("patientBmi", bmi); + // String temp = "" + bmi; + // bmiAsString = temp.substring(0, temp.indexOf('.') + 2); + // } + // } + // catch (Exception ex) { + // if (latestWeight != null && latestHeight != null) { + // log.error("Failed to calculate BMI even though a weight and height were found", ex); + // } + // } + + // model.put("patientBmiAsString", bmiAsString); + // } else { + // model.put("patientObs", new HashSet()); + // } + if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); Integer startIndex = getStartIndexParameter(request); @@ -210,56 +312,46 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons Person person = (Person) p; List persons = Collections.singletonList(person); - // Get paginated observations + // Get paginated observations for display List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, null, Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); - // Get all observations for BMI calculation - List allObs = Context.getObsService().getObservations(persons, null, null, null, null, null, - null, null, null, null, null, false); - model.put("patientObs", paginatedObs); // Handle BMI calculation - Obs latestWeight = null; - Obs latestHeight = null; String bmiAsString = "?"; try { String weightString = as.getGlobalProperty("concept.weight"); + String heightString = as.getGlobalProperty("concept.height"); + ConceptNumeric weightConcept = null; + ConceptNumeric heightConcept = null; + Obs latestWeight = null; + Obs latestHeight = null; + if (StringUtils.hasLength(weightString)) { weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); + List weightObs = Context.getObsService().getObservations(persons, null, + Collections.singletonList(weightConcept), null, null, null, + Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + if (!weightObs.isEmpty()) { + latestWeight = weightObs.get(0); + } } - String heightString = as.getGlobalProperty("concept.height"); - ConceptNumeric heightConcept = null; if (StringUtils.hasLength(heightString)) { heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); - } - - // Find weight and height from all observations - for (Obs obs : allObs) { - if (obs.getConcept().equals(weightConcept)) { - if (latestWeight == null - || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { - latestWeight = obs; - } - } else if (obs.getConcept().equals(heightConcept) - && (latestHeight == null || obs.getObsDatetime().compareTo( - latestHeight.getObsDatetime()) > 0)) { - latestHeight = obs; + List heightObs = Context.getObsService().getObservations(persons, null, + Collections.singletonList(heightConcept), null, null, null, + Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + if (!heightObs.isEmpty()) { + latestHeight = heightObs.get(0); } } - if (latestWeight != null) { - model.put("patientWeight", latestWeight); - } - if (latestHeight != null) { - model.put("patientHeight", latestHeight); - } - - if (latestWeight != null && latestHeight != null) { + if (latestWeight != null && latestHeight != null && weightConcept != null + && heightConcept != null) { double weightInKg; double heightInM; @@ -290,9 +382,7 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons } } catch (Exception ex) { - if (latestWeight != null && latestHeight != null) { - log.error("Failed to calculate BMI even though a weight and height were found", ex); - } + log.error("Failed to calculate BMI", ex); } model.put("patientBmiAsString", bmiAsString); From 568c1f965cc29f8127f6f576f4a0b29ffbfdf8b1 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:13:46 +0300 Subject: [PATCH 15/16] Remove commented out code --- .../web/controller/PortletController.java | 102 ------------------ 1 file changed, 102 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index d032370a..385278fd 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -203,108 +203,6 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons model.put("activeVisits", Context.getVisitService().getActiveVisitsByPatient(p)); } - // if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { - // Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); - // Integer startIndex = getStartIndexParameter(request); - - // Person person = (Person) p; - // List persons = Collections.singletonList(person); - - // // Get paginated observations - // String weightString = as.getGlobalProperty("concept.weight"); - // String heightString = as.getGlobalProperty("concept.height"); - // // List concepts = new ArrayList(); - // // concepts.add(GeneralUtils.getConcept(weightString)); - // List paginatedObs = Context.getObsService().getObservations(persons, null, null, null, null, - // null, Collections.singletonList("obsDatetime desc"), limit, startIndex, null, null, false); - - // // Get all observations for BMI calculation - // List weightObs = Context.getObsService().getObservations(persons, null, Collections.singletonList(GeneralUtils.getConcept(weightString)), null, null, null, - // Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); - - // List heightObs = Context.getObsService().getObservations(persons, null, Collections.singletonList(GeneralUtils.getConcept(heightString)), null, null, null, - // Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); - - // model.put("patientObs", paginatedObs); - - // // Handle BMI calculation - // Obs latestWeight = weightObs.get(0); - // Obs latestHeight = heightObs.get(0); - // String bmiAsString = "?"; - - // try { - // ConceptNumeric weightConcept = null; - // if (StringUtils.hasLength(weightString)) { - // weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); - // } - - // ConceptNumeric heightConcept = null; - // if (StringUtils.hasLength(heightString)) { - // heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); - // } - - // // Find weight and height from all observations - // // for (Obs obs : allObs) { - // // if (obs.getConcept().equals(weightConcept)) { - // // if (latestWeight == null - // // || obs.getObsDatetime().compareTo(latestWeight.getObsDatetime()) > 0) { - // // latestWeight = obs; - // // } - // // } else if (obs.getConcept().equals(heightConcept) - // // && (latestHeight == null || obs.getObsDatetime().compareTo( - // // latestHeight.getObsDatetime()) > 0)) { - // // latestHeight = obs; - // // } - // // } - - // if (latestWeight != null) { - // model.put("patientWeight", latestWeight); - // } - // if (latestHeight != null) { - // model.put("patientHeight", latestHeight); - // } - - // if (latestWeight != null && latestHeight != null) { - // double weightInKg; - // double heightInM; - - // if (weightConcept.getUnits().equalsIgnoreCase("kg")) { - // weightInKg = latestWeight.getValueNumeric(); - // } else if (weightConcept.getUnits().equalsIgnoreCase("lb")) { - // weightInKg = latestWeight.getValueNumeric() * 0.45359237; - // } else { - // throw new IllegalArgumentException("Can't handle units of weight concept: " - // + weightConcept.getUnits()); - // } - - // if (heightConcept.getUnits().equalsIgnoreCase("cm")) { - // heightInM = latestHeight.getValueNumeric() / 100; - // } else if (heightConcept.getUnits().equalsIgnoreCase("m")) { - // heightInM = latestHeight.getValueNumeric(); - // } else if (heightConcept.getUnits().equalsIgnoreCase("in")) { - // heightInM = latestHeight.getValueNumeric() * 0.0254; - // } else { - // throw new IllegalArgumentException("Can't handle units of height concept: " - // + heightConcept.getUnits()); - // } - - // double bmi = weightInKg / (heightInM * heightInM); - // model.put("patientBmi", bmi); - // String temp = "" + bmi; - // bmiAsString = temp.substring(0, temp.indexOf('.') + 2); - // } - // } - // catch (Exception ex) { - // if (latestWeight != null && latestHeight != null) { - // log.error("Failed to calculate BMI even though a weight and height were found", ex); - // } - // } - - // model.put("patientBmiAsString", bmiAsString); - // } else { - // model.put("patientObs", new HashSet()); - // } - if (Context.hasPrivilege(PrivilegeConstants.GET_OBS)) { Integer limit = getLimitParameter(request, as, "dashboard.observations.maximumNumberToShow"); Integer startIndex = getStartIndexParameter(request); From 9bf378f5039f43f0bfff8ff0193cb27b29857cf8 Mon Sep 17 00:00:00 2001 From: AJAL ODORA JONATHAN <43242517+ODORA0@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:55:40 +0300 Subject: [PATCH 16/16] Add model for latestHeight and weight --- .../org/openmrs/web/controller/PortletController.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/PortletController.java b/omod/src/main/java/org/openmrs/web/controller/PortletController.java index 385278fd..8fc675d2 100644 --- a/omod/src/main/java/org/openmrs/web/controller/PortletController.java +++ b/omod/src/main/java/org/openmrs/web/controller/PortletController.java @@ -231,20 +231,22 @@ public ModelAndView handleRequest(HttpServletRequest request, HttpServletRespons if (StringUtils.hasLength(weightString)) { weightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(weightString).getConceptId()); List weightObs = Context.getObsService().getObservations(persons, null, - Collections.singletonList(weightConcept), null, null, null, - Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + Collections.singletonList(weightConcept), null, null, null, + Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); if (!weightObs.isEmpty()) { latestWeight = weightObs.get(0); + model.put("patientWeight", latestWeight); } } if (StringUtils.hasLength(heightString)) { heightConcept = cs.getConceptNumeric(GeneralUtils.getConcept(heightString).getConceptId()); List heightObs = Context.getObsService().getObservations(persons, null, - Collections.singletonList(heightConcept), null, null, null, - Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); + Collections.singletonList(heightConcept), null, null, null, + Collections.singletonList("obsDatetime desc"), 1, null, null, null, false); if (!heightObs.isEmpty()) { latestHeight = heightObs.get(0); + model.put("patientHeight", latestHeight); } }