From 97bd3541191de6643a9c9ee0bf6af85f23bcaf83 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Tue, 27 Aug 2024 13:49:51 +0300 Subject: [PATCH 01/30] Initial commit --- .../web/controller/ConceptFormController.java | 2 ++ .../main/webapp/admin/dictionary/concept.jsp | 28 +++++++++++++++++++ omod/src/main/webapp/dictionary/concept.jsp | 28 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 50fcb110..ca3d078b 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -459,6 +459,8 @@ public class ConceptFormBackingObject { public Collection activeAttributes; + // public List conceptReferenceRanges = new ArrayList<>(); + /** * Default constructor must take in a Concept object to create itself * diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index 7e4883f9..ea6ecc0e 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,6 +319,34 @@ + + "> + + + + + style="display:none"> + + + + + + + + + class='evenRow'> + + + + + + + + + +
+ + diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index 73692904..93651694 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,6 +322,34 @@ + + "> + + + + + style="display:none"> + + + + + + + + + class='evenRow'> + + + + + + + + + +
+ + From 45c5846a2908f6b09274d48053a558d736bd9603 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 28 Aug 2024 11:00:08 +0300 Subject: [PATCH 02/30] Concept references header on the UI --- .../web/controller/ConceptFormController.java | 9 ++++- .../main/webapp/admin/dictionary/concept.jsp | 28 --------------- omod/src/main/webapp/dictionary/concept.jsp | 28 --------------- .../main/webapp/dictionary/conceptForm.jsp | 33 +++++++++++++++++- .../concept/ConceptFormControllerTest.java | 34 +++++++++++++++++++ .../DownloadDictionaryServletTest.java | 4 +-- 6 files changed, 76 insertions(+), 60 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index ca3d078b..41764b18 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -40,6 +40,7 @@ import org.openmrs.ConceptMapType; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; +import org.openmrs.ConceptReferenceRange; import org.openmrs.ConceptReferenceTerm; import org.openmrs.ConceptSet; import org.openmrs.Drug; @@ -459,7 +460,7 @@ public class ConceptFormBackingObject { public Collection activeAttributes; - // public List conceptReferenceRanges = new ArrayList<>(); + public Set referenceRanges = new HashSet<>(); /** * Default constructor must take in a Concept object to create itself @@ -529,6 +530,11 @@ public ConceptFormBackingObject(Concept concept) { } this.activeAttributes = concept.getActiveAttributes(); + + if (concept.getDatatype().getName().equals("Numeric") + && concept instanceof ConceptNumeric) { + this.referenceRanges = ((ConceptNumeric) concept).getReferenceRanges(); + } } /** @@ -663,6 +669,7 @@ public Concept getConceptFromFormData() { cn.setAllowDecimal(allowDecimal); cn.setDisplayPrecision(displayPrecision); cn.setUnits(units); + cn.setReferenceRanges(referenceRanges); concept = cn; diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index ea6ecc0e..7e4883f9 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,34 +319,6 @@ - - "> - - - - - style="display:none"> - - - - - - - - - class='evenRow'> - - - - - - - - - -
- - diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index 93651694..73692904 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,34 +322,6 @@ - - "> - - - - - style="display:none"> - - - - - - - - - class='evenRow'> - - - - - - - - - -
- - diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index fe7835bd..1bc97fc8 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -789,7 +789,7 @@ - @@ -815,6 +815,37 @@ + Concept.referenceRanges + "> + + + + + style="display:none"> + + + + + + + + + + + class='evenRow'> + + + + + + + + + + +
+ + diff --git a/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java index 0a52c71e..7152ec2b 100644 --- a/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java @@ -15,6 +15,7 @@ import org.mockito.Mockito; import org.openmrs.ConceptMap; import org.openmrs.ConceptNumeric; +import org.openmrs.ConceptReferenceRange; import org.openmrs.web.controller.ConceptFormController; import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; @@ -56,4 +57,37 @@ public void ConceptFormBackingObject_shouldCopyNumericAttributes() { org.junit.Assert.assertEquals("ml", conceptFormBackingObject.getUnits()); } + + @Test + public void testConceptFormBackingObject_shouldSetReferenceRangeAttributes() { + ConceptReferenceRange referenceRange = Mockito.mock(ConceptReferenceRange.class); + ConceptNumeric conceptNumeric = Mockito.mock(ConceptNumeric.class); + + Mockito.when(referenceRange.getHiAbsolute()).thenReturn(5.2); + Mockito.when(referenceRange.getLowAbsolute()).thenReturn(1.0); + + Mockito.when(referenceRange.getHiCritical()).thenReturn(4.1); + Mockito.when(referenceRange.getLowCritical()).thenReturn(2.1); + + Mockito.when(referenceRange.getLowNormal()).thenReturn(3.1); + Mockito.when(referenceRange.getHiNormal()).thenReturn(3.9); + + Mockito.when(referenceRange.getCriteria()).thenReturn(""); + + ConceptFormController controller = new ConceptFormController(); + ConceptReferenceRange conceptReferenceRange = controller.new ConceptFormBackingObject( + conceptNumeric).referenceRanges + .iterator().next(); + + org.junit.Assert.assertEquals(Double.valueOf(5.2), conceptReferenceRange.getHiAbsolute()); + org.junit.Assert.assertEquals(Double.valueOf(1.0), conceptReferenceRange.getLowAbsolute()); + + org.junit.Assert.assertEquals(Double.valueOf(4.1), conceptReferenceRange.getHiCritical()); + org.junit.Assert.assertEquals(Double.valueOf(2.1), conceptReferenceRange.getLowCritical()); + + org.junit.Assert.assertEquals(Double.valueOf(3.1), conceptReferenceRange.getLowNormal()); + org.junit.Assert.assertEquals(Double.valueOf(3.9), conceptReferenceRange.getHiNormal()); + + org.junit.Assert.assertEquals("", conceptReferenceRange.getCriteria()); + } } diff --git a/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java b/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java index e29b030a..5715de06 100644 --- a/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java +++ b/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java @@ -12,7 +12,7 @@ import java.util.Arrays; import java.util.List; -import javax.annotation.Resource; +//import javax.annotation.Resource; import org.junit.Assert; import org.junit.Test; @@ -38,7 +38,7 @@ public class DownloadDictionaryServletTest extends BaseModuleWebContextSensitive @Mock private ConceptService conceptService; - @Resource(name = "conceptDAO") + // @Resource(name = "conceptDAO") private ConceptDAO conceptDAO; @Test From 8004fd8e57acc1ca806c4a31873b4727ec2310d5 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 28 Aug 2024 14:44:25 +0300 Subject: [PATCH 03/30] Showing reference range title and table headers --- .../web/controller/ConceptFormController.java | 3 +- .../main/webapp/dictionary/conceptForm.jsp | 64 ++++++++++++------- .../DownloadDictionaryServletTest.java | 4 +- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 41764b18..b028043d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -531,8 +531,7 @@ public ConceptFormBackingObject(Concept concept) { this.activeAttributes = concept.getActiveAttributes(); - if (concept.getDatatype().getName().equals("Numeric") - && concept instanceof ConceptNumeric) { + if (concept.isNumeric() && concept instanceof ConceptNumeric) { this.referenceRanges = ((ConceptNumeric) concept).getReferenceRanges(); } } diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 1bc97fc8..6c707573 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -153,6 +153,7 @@ #addAnswerError{ margin-bottom: 0.5em; border: 1px dashed black; background: #FAA; line-height: 2em; text-align: center; display: none; } #headerRow th { text-align: center; } #footer { clear:both; } + #newReferenceRange { display: none; } @@ -789,7 +790,7 @@ - @@ -816,32 +817,47 @@ Concept.referenceRanges - "> - + + "/> - - style="display:none"> - - - - - - - - - - - class='evenRow'> - - - - - - - +
+ + + + + + + + + + + + + + class='evenRow'> + + + + + + + + + + + + + + -
 
diff --git a/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java b/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java index 5715de06..e29b030a 100644 --- a/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java +++ b/omod/src/test/java/org/openmrs/web/servlet/DownloadDictionaryServletTest.java @@ -12,7 +12,7 @@ import java.util.Arrays; import java.util.List; -//import javax.annotation.Resource; +import javax.annotation.Resource; import org.junit.Assert; import org.junit.Test; @@ -38,7 +38,7 @@ public class DownloadDictionaryServletTest extends BaseModuleWebContextSensitive @Mock private ConceptService conceptService; - // @Resource(name = "conceptDAO") + @Resource(name = "conceptDAO") private ConceptDAO conceptDAO; @Test From c6ee428eaca32fb0d76e46039d5337c8332cc8f2 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 29 Aug 2024 11:31:14 +0300 Subject: [PATCH 04/30] Concept reference form - restructured --- .../web/controller/ConceptFormController.java | 22 ++++++ omod/src/main/resources/messages.properties | 4 + .../main/webapp/dictionary/conceptForm.jsp | 73 ++++++++++++++----- .../scripts/dictionary/conceptForm.js | 30 +++++++- 4 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 omod/src/main/resources/messages.properties diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index b028043d..e9a316a8 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -945,6 +945,28 @@ public void setIndexTermsByLocale(Map> indexTermsByLoc public List
getFormsInUse() { return Context.getFormService().getFormsContainingConcept(concept); } + + /** + * Get reference ranges + * + * @return the referenceRanges + * + * @since 1.17.0 + */ + public Set getReferenceRanges() { + return referenceRanges; + } + + /** + * Sets reference ranges + * + * @param referenceRanges the referenceRanges to set + * + * @since 1.17.0 + */ + public void setReferenceRanges(Set referenceRanges) { + this.referenceRanges = referenceRanges; + } /** * Get the list of extensions/metadata and the specific instances of them that use this diff --git a/omod/src/main/resources/messages.properties b/omod/src/main/resources/messages.properties new file mode 100644 index 00000000..f7fc2ccd --- /dev/null +++ b/omod/src/main/resources/messages.properties @@ -0,0 +1,4 @@ +Concept.referenceRanges=Reference Ranges +Concept.referenceRanges.criteria=Criteria +Concept.referenceRanges.help=Defines reference ranges of this concept with a criteria +Concept.referenceRanges.add=Add a Reference Range \ No newline at end of file diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 6c707573..9ae84be1 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -78,6 +78,11 @@ $j(".hideableEle").hide(); }); + $j(document).ready(function(){ + if(${fn:length(command.referenceRanges)} == 0) + $j(".hideable").hide(); + }); + @@ -816,13 +821,13 @@ - Concept.referenceRanges + "/> - - +
+ @@ -834,28 +839,60 @@ - + class='evenRow'> - - - - - - - + + + + + + + + - - + + diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index 1fc7aa8a..f44c3c8a 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -433,7 +433,7 @@ function addConceptMapping(initialSizeOfClonedSiblings){ input.id = 'term[' + index + '].name'; } } - + //find the select element and set the name attribute for the conceptSource and map type for (var i in selects) { var select = selects[i]; @@ -469,4 +469,32 @@ function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, }); } +/** + * Method is invoked to add a new reference range + * @param initialSizeOfReferenceRanges the number of mappings on page load + */ +function addReferenceRanges(initialSizeOfReferenceRanges){ + + var inputNamePrefix = 'referenceRanges'; + var newRow = cloneElement('newReferenceRange', initialSizeOfReferenceRanges, inputNamePrefix); + + if(newRow){ + newRow.id = ""; + var index = numberOfClonedElements['newReferenceRange']; + var inputs = newRow.getElementsByTagName("input"); + + for (var x = 0; x < inputs.length; x++) { + var input = inputs[x]; + + if (input && input.name == 'termId' && input.type == 'hidden') { + input.name = inputNamePrefix+'[' + index + '].conceptReference'; + input.id = inputNamePrefix+'[' + index + '].conceptReference'; + } + } + + if(!$j("#headerRow").is(":visible")) + $j(".hideable").show(); + } +} + document.onkeypress = hotkeys; \ No newline at end of file From 0b72cf4dc38a4b98cf950ca7a0996654ab307d50 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 29 Aug 2024 18:42:31 +0300 Subject: [PATCH 05/30] Showing saved data --- .../web/controller/ConceptFormController.java | 9 ++- .../webapp/admin/dictionary/conceptForm.jsp | 5 ++ .../main/webapp/dictionary/conceptForm.jsp | 79 ++++++++++--------- .../scripts/dictionary/conceptForm.js | 51 ++++++------ 4 files changed, 81 insertions(+), 63 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index e9a316a8..27b38a4e 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -520,6 +520,8 @@ public ConceptFormBackingObject(Concept concept) { this.allowDecimal = cn.getAllowDecimal(); this.displayPrecision = cn.getDisplayPrecision(); this.units = cn.getUnits(); + + this.referenceRanges = cn.getReferenceRanges(); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; this.handlerKey = complex.getHandler(); @@ -530,10 +532,6 @@ public ConceptFormBackingObject(Concept concept) { } this.activeAttributes = concept.getActiveAttributes(); - - if (concept.isNumeric() && concept instanceof ConceptNumeric) { - this.referenceRanges = ((ConceptNumeric) concept).getReferenceRanges(); - } } /** @@ -669,6 +667,9 @@ public Concept getConceptFromFormData() { cn.setDisplayPrecision(displayPrecision); cn.setUnits(units); cn.setReferenceRanges(referenceRanges); + + // Set the reference ranges from the form data + cn.setReferenceRanges(this.referenceRanges); concept = cn; diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index 578c6996..f8c07667 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -78,6 +78,11 @@ $j(".hideableEle").hide(); }); + $j(document).ready(function(){ + if(${fn:length(command.referenceRanges)} == 0) + $j(".referenceRangeHeader").hide(); + }); + diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 9ae84be1..b4456c0e 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -74,13 +74,13 @@ } $j(document).ready(function(){ - if(${fn:length(command.conceptMappings)} == 0) + if(${fn:length(command.referenceRanges)} == 0) $j(".hideableEle").hide(); }); $j(document).ready(function(){ if(${fn:length(command.referenceRanges)} == 0) - $j(".hideable").hide(); + $j(".referenceRangeHeader").hide(); }); @@ -827,7 +827,7 @@ + + + + diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index 73692904..7c434bc4 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,6 +322,35 @@
 
class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + class='evenRow'> + " readonly="readonly" /> + + + + ${status.errorMessage} + +
+ + + + + + + + + + + + +
- + @@ -838,51 +838,56 @@ - - - class='evenRow'> - - - - - - - - - - + + class='evenRow'> + + + + + + + + + + + + + + + + - +
 
class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - class='evenRow'> - " readonly="readonly" /> - - - - ${status.errorMessage} - -
+ + + + class='evenRow'> + + class='evenRow'> + + class='evenRow'> + + class='evenRow'> + + class='evenRow'> + + + + + ${status.errorMessage} + +
+ onClick="addReferenceRanges(${fn:length(command.referenceRanges)})" /> diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index f44c3c8a..4fb2dfd4 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -453,36 +453,21 @@ function addConceptMapping(initialSizeOfClonedSiblings){ } } -function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){ - var selectOption = document.getElementById(sourceSelectElementId); - // set up the autocomplete on the conceptReferenceTerm input box for the new mapping - new AutoComplete(displayInputId, new CreateCallback().conceptReferenceTermCallback(selectOption), { - select: function(event, ui) { - jquerySelectEscaped(hiddenElementId).val(ui.item.object.conceptReferenceTermId); - //set the concept source in the source dropdown to match that of the selected term - selectOption.value = ui.item.object.conceptSourceId; - //display the name of the term - if(document.getElementById(nameInputId)) - document.getElementById(nameInputId).value = ui.item.object.name; - }, - placeholder:omsgs.referencTermSearchPlaceholder - }); -} - /** * Method is invoked to add a new reference range * @param initialSizeOfReferenceRanges the number of mappings on page load */ -function addReferenceRanges(initialSizeOfReferenceRanges){ - - var inputNamePrefix = 'referenceRanges'; - var newRow = cloneElement('newReferenceRange', initialSizeOfReferenceRanges, inputNamePrefix); +function addReferenceRanges(initialSizeOfReferenceRanges) { + var inputNamePrefix = 'referenceRanges'; + var newRow = cloneElement('newReferenceRange', initialSizeOfReferenceRanges, inputNamePrefix); if(newRow){ newRow.id = ""; var index = numberOfClonedElements['newReferenceRange']; var inputs = newRow.getElementsByTagName("input"); + console.log("Index of cloned element:", index); + for (var x = 0; x < inputs.length; x++) { var input = inputs[x]; @@ -492,9 +477,31 @@ function addReferenceRanges(initialSizeOfReferenceRanges){ } } - if(!$j("#headerRow").is(":visible")) - $j(".hideable").show(); + // Insert the new row before the last row + var referenceTable = document.getElementById("referenceTable"); + // referenceTable.insertBefore(newRow, referenceTable.lastElementChild); + referenceTable.appendChild(newRow); + console.log("New row inserted into the table."); } + + if(!$j("#headerRow").is(":visible")) + $j(".referenceRangeHeader").show(); +} + +function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){ + var selectOption = document.getElementById(sourceSelectElementId); + // set up the autocomplete on the conceptReferenceTerm input box for the new mapping + new AutoComplete(displayInputId, new CreateCallback().conceptReferenceTermCallback(selectOption), { + select: function(event, ui) { + jquerySelectEscaped(hiddenElementId).val(ui.item.object.conceptReferenceTermId); + //set the concept source in the source dropdown to match that of the selected term + selectOption.value = ui.item.object.conceptSourceId; + //display the name of the term + if(document.getElementById(nameInputId)) + document.getElementById(nameInputId).value = ui.item.object.name; + }, + placeholder:omsgs.referencTermSearchPlaceholder + }); } document.onkeypress = hotkeys; \ No newline at end of file From 3d6c0886b16d0c51f3c393ffa4067a4a72ab4a12 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Fri, 30 Aug 2024 18:27:06 +0300 Subject: [PATCH 06/30] Updating concept page with reference ranges --- .../web/controller/ConceptFormController.java | 5 +- .../main/webapp/admin/dictionary/concept.jsp | 29 +++++++++++ omod/src/main/webapp/dictionary/concept.jsp | 29 +++++++++++ .../main/webapp/dictionary/conceptForm.jsp | 48 ++++--------------- .../scripts/dictionary/conceptForm.js | 6 +-- 5 files changed, 75 insertions(+), 42 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 27b38a4e..1b9fba19 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -668,7 +668,10 @@ public Concept getConceptFromFormData() { cn.setUnits(units); cn.setReferenceRanges(referenceRanges); - // Set the reference ranges from the form data + System.out.println("****************** setting reference ranges"); + System.out.println("****************** size: " + this.referenceRanges.size()); + + cn.setReferenceRanges(this.referenceRanges); concept = cn; diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index 7e4883f9..fbd626fc 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,6 +319,35 @@
"> + + + + style="display:none"> + + + + + + + + + + class='evenRow'> + + + + + + + + + +
+
+ + "> + + + + + style="display:none"> + + + + + + + + + + class='evenRow'> + + + + + + + + + +
+ + diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index b4456c0e..fafeeb93 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -834,54 +834,26 @@ -   - - class='evenRow'> - - - - - - - class='evenRow'> - - - class='evenRow'> - - - class='evenRow'> - - - class='evenRow'> - - - class='evenRow'> - - + + class='evenRow'> + + + + + + + - + ${status.errorMessage} - - - - - - - - - - - - diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index 4fb2dfd4..3c8bab39 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -471,9 +471,9 @@ function addReferenceRanges(initialSizeOfReferenceRanges) { for (var x = 0; x < inputs.length; x++) { var input = inputs[x]; - if (input && input.name == 'termId' && input.type == 'hidden') { - input.name = inputNamePrefix+'[' + index + '].conceptReference'; - input.id = inputNamePrefix+'[' + index + '].conceptReference'; + if (input) { + input.name = inputNamePrefix+'[' + index + '].' + input.name.split('.')[1]; + input.id = inputNamePrefix+'[' + index + '].' + input.id.split('.')[1]; } } From 1af1c3de744569468f9805b43318b921f9e82fc5 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Mon, 2 Sep 2024 01:21:02 +0300 Subject: [PATCH 07/30] Successfully saving new data --- .../web/controller/ConceptFormController.java | 41 +++++++----- .../main/webapp/dictionary/conceptForm.jsp | 62 ++++++++++--------- .../scripts/dictionary/conceptForm.js | 32 ++++++---- 3 files changed, 75 insertions(+), 60 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 1b9fba19..91c166f8 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -460,7 +460,7 @@ public class ConceptFormBackingObject { public Collection activeAttributes; - public Set referenceRanges = new HashSet<>(); + public List referenceRanges; /** * Default constructor must take in a Concept object to create itself @@ -521,7 +521,8 @@ public ConceptFormBackingObject(Concept concept) { this.displayPrecision = cn.getDisplayPrecision(); this.units = cn.getUnits(); - this.referenceRanges = cn.getReferenceRanges(); + this.referenceRanges = ListUtils.lazyList(new ArrayList<>(cn.getReferenceRanges()), + FactoryUtils.instantiateFactory(ConceptReferenceRange.class)); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; this.handlerKey = complex.getHandler(); @@ -666,13 +667,11 @@ public Concept getConceptFromFormData() { cn.setAllowDecimal(allowDecimal); cn.setDisplayPrecision(displayPrecision); cn.setUnits(units); - cn.setReferenceRanges(referenceRanges); - - System.out.println("****************** setting reference ranges"); - System.out.println("****************** size: " + this.referenceRanges.size()); - - - cn.setReferenceRanges(this.referenceRanges); + + for (ConceptReferenceRange referenceRange : this.referenceRanges) { + referenceRange.setConceptNumeric(cn); + cn.addReferenceRange(referenceRange); + } concept = cn; @@ -949,29 +948,37 @@ public void setIndexTermsByLocale(Map> indexTermsByLoc public List getFormsInUse() { return Context.getFormService().getFormsContainingConcept(concept); } - + /** * Get reference ranges - * + * * @return the referenceRanges - * * @since 1.17.0 */ - public Set getReferenceRanges() { + public List getReferenceRanges() { return referenceRanges; } - + /** * Sets reference ranges - * + * * @param referenceRanges the referenceRanges to set - * * @since 1.17.0 */ - public void setReferenceRanges(Set referenceRanges) { + public void setReferenceRanges(List referenceRanges) { this.referenceRanges = referenceRanges; } + /** + * Adds a new reference range to the list of reference ranges + * + * @param referenceRange the referenceRange to add + * @since 1.17.0 + */ + public void addReferenceRange(ConceptReferenceRange referenceRange) { + getReferenceRanges().add(referenceRange); + } + /** * Get the list of extensions/metadata and the specific instances of them that use this * concept. diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index fafeeb93..aa5f186c 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -838,41 +838,43 @@   - class='evenRow'> - - - - - - - - - - - ${status.errorMessage} - - - + + + + + + + + + + + + + ${status.errorMessage} + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + - diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index 3c8bab39..4aaa1ac1 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -466,26 +466,32 @@ function addReferenceRanges(initialSizeOfReferenceRanges) { var index = numberOfClonedElements['newReferenceRange']; var inputs = newRow.getElementsByTagName("input"); - console.log("Index of cloned element:", index); - for (var x = 0; x < inputs.length; x++) { var input = inputs[x]; - if (input) { - input.name = inputNamePrefix+'[' + index + '].' + input.name.split('.')[1]; - input.id = inputNamePrefix+'[' + index + '].' + input.id.split('.')[1]; - } + if (input && input.type == 'text') { + input.id = inputNamePrefix + '[' + index + '].' + input.name.split('.')[1] + input.name = inputNamePrefix + '[' + index + '].' + input.name.split('.')[1] + } } - // Insert the new row before the last row - var referenceTable = document.getElementById("referenceTable"); - // referenceTable.insertBefore(newRow, referenceTable.lastElementChild); - referenceTable.appendChild(newRow); - console.log("New row inserted into the table."); + + if(!$j("#headerRow").is(":visible")) + $j(".referenceRangeHeader").show(); } +} - if(!$j("#headerRow").is(":visible")) - $j(".referenceRangeHeader").show(); +/** + * Handles deleting and update visibility of reference range fields + * + * @param btn + * the source object of event + * @param key + * the key object for receiving the save key +*/ +function removeReferenceRangeElement(btn, key) { + removeParentElement(btn.parentNode); + numberOfClonedElements[key]--; } function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){ From 9bcb15c3e548e5fa55e07f3ceaad22e5cce5cbb4 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Mon, 2 Sep 2024 13:11:31 +0300 Subject: [PATCH 08/30] Hiding reference ranges when concept type is not numeric --- .../main/webapp/dictionary/conceptForm.jsp | 116 +++++++++--------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index aa5f186c..b7fe7621 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -821,63 +821,65 @@ - - - "/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- - - ${status.errorMessage} - -
- -
- - + + + + "/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ + + ${status.errorMessage} + +
+ +
+ + +
From 24963af267e101933abe4cdc3ce0ac80ea8c3c4a Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Mon, 2 Sep 2024 16:59:45 +0300 Subject: [PATCH 09/30] Updating version for testing purposes --- .../web/servlet/mvc/AbstractWizardFormController.java | 4 +++- pom.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java b/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java index 200ff95a..2d95fafc 100644 --- a/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java +++ b/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java @@ -654,7 +654,9 @@ protected int getTargetPage(HttpServletRequest request, Object command, Errors e * @see #PARAM_TARGET */ protected int getTargetPage(HttpServletRequest request, int currentPage) { - return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage); + return 0; + // TODO REVERT THIS AFTER TESTING IS DONE + // return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage); } /** diff --git a/pom.xml b/pom.xml index e861ba92..e5878b34 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 2.0.0 + 2.7.0-SNAPSHOT UTF-8 1.8 From c888df09b71767f85ede00304fc37e2edea28289 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 4 Sep 2024 19:14:09 +0300 Subject: [PATCH 10/30] Removing an existing row on the UI --- .../web/controller/ConceptFormController.java | 17 +++++++++++++++-- .../main/webapp/dictionary/conceptForm.jsp | 19 ++++++++++--------- .../scripts/dictionary/conceptForm.js | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 91c166f8..65610a24 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -21,6 +21,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -669,8 +670,20 @@ public Concept getConceptFromFormData() { cn.setUnits(units); for (ConceptReferenceRange referenceRange : this.referenceRanges) { - referenceRange.setConceptNumeric(cn); - cn.addReferenceRange(referenceRange); + if (referenceRange != null) { + if (referenceRange.getUuid() != null) { + // Handle already saved references + + if (referenceRange.getUuid().isEmpty()) { + // reference range was removed + cn.getReferenceRanges().remove(referenceRange); + } + } else { + // Add new reference range + referenceRange.setConceptNumeric(cn); + cn.addReferenceRange(referenceRange); + } + } } concept = cn; diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index b7fe7621..660ae975 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -840,21 +840,22 @@ - - - - - - - - + + + + + + + + - + ${status.errorMessage} + diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index 4aaa1ac1..3f488642 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -494,6 +494,22 @@ function removeReferenceRangeElement(btn, key) { numberOfClonedElements[key]--; } +/** + * Handles deleting and updating visibility of reference range fields. + * The removed row is marked for deletion. + * + * @param btn + * the source object of event + * @param index + * the index of the row to be deleted +*/ +function removeReferenceRangeElementByIndex(btn, index) { + var row = document.getElementById('row-' + index); + removeParentElement(btn.parentNode); + + document.getElementById('removeMarker-' + index).value = ""; +} + function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){ var selectOption = document.getElementById(sourceSelectElementId); // set up the autocomplete on the conceptReferenceTerm input box for the new mapping From 269538305e7fc75edb387929a8b9aad01fd05986 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 5 Sep 2024 17:06:36 +0300 Subject: [PATCH 11/30] Adding tests --- .../web/controller/ConceptFormController.java | 70 +++++++-- .../controller/ConceptFormControllerTest.java | 140 ++++++++++++++++++ 2 files changed, 194 insertions(+), 16 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 65610a24..89c60780 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -273,6 +273,8 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse validateConceptUsesPersistedObjects(concept, errors); + validateConceptReferenceRange(concept, errors); + if (!errors.hasErrors()) { if (action.equals(msa.getMessage("Concept.cancel"))) { return new ModelAndView(new RedirectView("index.htm")); @@ -312,6 +314,35 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse return new ModelAndView(new RedirectView(getFormView())); } + void validateConceptReferenceRange(Concept concept, BindException errors) { + if (concept.isNumeric()) { + ConceptNumeric conceptNumeric = (ConceptNumeric) concept; + Set referenceRanges = conceptNumeric.getReferenceRanges(); + + int index = 0; + for (ConceptReferenceRange referenceRange : referenceRanges) { + + if (referenceRange.getUuid() == null) { + if (conceptNumeric.getHiAbsolute() != null && referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { + errors.pushNestedPath("referenceRanges[" + index + "].hiAbsolute"); + errors.rejectValue("conceptSource", "error.value.outOfRange.high", + "High Absolute in reference range cannot be higher than high absolute of the concept"); + errors.popNestedPath(); + } + + if (conceptNumeric.getLowAbsolute() != null && referenceRange.getHiAbsolute() < conceptNumeric.getHiAbsolute()) { + errors.pushNestedPath("referenceRanges[" + index + "].lowAbsolute"); + errors.rejectValue("conceptSource", "error.value.outOfRange.low", + "Low Absolute in reference range cannot be lower than low absolute of the concept"); + errors.popNestedPath(); + } + } + + index++; + } + } + } + /** * @param concept * @param errors @@ -669,22 +700,7 @@ public Concept getConceptFromFormData() { cn.setDisplayPrecision(displayPrecision); cn.setUnits(units); - for (ConceptReferenceRange referenceRange : this.referenceRanges) { - if (referenceRange != null) { - if (referenceRange.getUuid() != null) { - // Handle already saved references - - if (referenceRange.getUuid().isEmpty()) { - // reference range was removed - cn.getReferenceRanges().remove(referenceRange); - } - } else { - // Add new reference range - referenceRange.setConceptNumeric(cn); - cn.addReferenceRange(referenceRange); - } - } - } + setConceptReferenceRanges(cn); concept = cn; @@ -702,6 +718,28 @@ public Concept getConceptFromFormData() { return concept; } + /** + * This method adds new reference ranges to concept numeric. If an existing reference range + * was removed, then we remove it from concept numeric + * + * @param cn ConceptNumeric + */ + private void setConceptReferenceRanges(ConceptNumeric cn) { + for (ConceptReferenceRange referenceRange : this.referenceRanges) { + if (referenceRange != null) { + if (referenceRange.getUuid() != null) { + if (referenceRange.getUuid().isEmpty()) { + cn.getReferenceRanges().remove(referenceRange); + } + } else { + // Add new reference range + referenceRange.setConceptNumeric(cn); + cn.addReferenceRange(referenceRange); + } + } + } + } + /** * Builds a white-space separated list of concept ids belonging to a concept set * diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index 5c7e5ecd..d236ca62 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -38,6 +38,7 @@ import org.openmrs.ConceptMapType; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; +import org.openmrs.ConceptReferenceRange; import org.openmrs.ConceptReferenceTerm; import org.openmrs.ConceptReferenceTermMap; import org.openmrs.ConceptSource; @@ -1314,4 +1315,143 @@ public void shouldSetAttributesToVoidIfTheValueIsNotSet() throws Exception { Assert.assertTrue(((ConceptAttribute) (concept.getAttributes().toArray()[0])).getVoided()); Assert.assertFalse(errors.hasErrors()); } + + /** + * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + */ + @Test + public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() throws Exception { + ConceptService cs = Context.getConceptService(); + + ConceptNumeric conceptNumeric = cs.getConceptNumeric(4090); + assertNotNull(conceptNumeric); + int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + + ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + mockRequest.setMethod("POST"); + mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + + ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + assertNotNull(mav); + assertTrue(mav.getModel().isEmpty()); + + assertEquals(initialConceptMappingCount + 1, cs.getConceptReferenceRangesByConceptId(conceptNumeric.getConceptId())); + } + + /** + * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + */ + @Test + public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() throws Exception { + ConceptService cs = Context.getConceptService(); + final String conceptName = "new concept"; + // make sure the concept doesn't already exist + Concept newConcept = cs.getConceptByName(conceptName); + assertNull(newConcept); + + ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + mockRequest.setMethod("POST"); + mockRequest.setParameter("action", ""); + mockRequest.setParameter("namesByLocale[en_GB].name", conceptName); + mockRequest.setParameter("descriptionsByLocale[en_GB].description", "some description"); + mockRequest.setParameter("concept.datatype", "1"); + mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + + ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + assertNotNull(mav); + assertTrue(mav.getModel().isEmpty()); + + Concept createdConcept = cs.getConceptByName(conceptName); + assertNotNull(createdConcept); + assertTrue(createdConcept instanceof ConceptNumeric); + Assert.assertEquals(1, ((ConceptNumeric) createdConcept).getReferenceRanges().size()); + } + + /** + * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + */ + @Test + public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyData() throws Exception { + ConceptService cs = Context.getConceptService(); + + int conceptId = 4090; + ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); + assertNotNull(conceptNumeric); + int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + + ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + mockRequest.setMethod("POST"); + mockRequest.setParameter("action", ""); + mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); + mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + + ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + assertNotNull(mav); + assertTrue(mav.getModel().isEmpty()); + + assertEquals(initialConceptMappingCount, cs.getConceptReferenceRangesByConceptId(conceptId).size()); + } + + /** + * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + */ + @Test + public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() throws Exception { + ConceptService cs = Context.getConceptService(); + int conceptId = 4090; + + // make sure the concept already exists and has some concept mappings + ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); + assertNotNull(conceptNumeric); + int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + assertTrue(initialConceptMappingCount > 0); + + ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + mockRequest.setMethod("POST"); + mockRequest.setParameter("action", ""); + mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); + mockRequest.setParameter("referenceRanges[0].uuid", ""); + + ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + assertNotNull(mav); + assertTrue(mav.getModel().isEmpty()); + + assertEquals(initialConceptMappingCount - 1, cs.getConceptReferenceRangesByConceptId(conceptId).size()); + } + + /** + * @see ConceptFormController#validateConceptReferenceRange(Concept, BindException) + */ + @Test + public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound() { + ConceptNumeric conceptNumeric = new ConceptNumeric(); + ConceptReferenceRange referenceRange = new ConceptReferenceRange(); + referenceRange.setHiAbsolute(1100.0); + referenceRange.setLowAbsolute(1.0); + conceptNumeric.addReferenceRange(referenceRange); + BindException errors = new BindException(conceptNumeric, "conceptNumeric"); + new ConceptFormController().validateConceptReferenceRange(conceptNumeric, errors); + Assert.assertEquals(1, errors.getErrorCount()); + assertTrue(errors.hasFieldErrors("referenceRanges[0].hiAbsolute")); + assertTrue(errors.hasFieldErrors("referenceRanges[0].lowAbsolute")); + } } From 71860fdbc42909e78a27af1eb3f3cf68cdc35a12 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 5 Sep 2024 20:26:09 +0300 Subject: [PATCH 12/30] Hiding and showing referenceRange row on conceptForm --- .../web/controller/ConceptFormController.java | 43 ++++--- .../main/webapp/admin/dictionary/concept.jsp | 58 +++++---- .../webapp/admin/dictionary/conceptForm.jsp | 58 +++++++++ omod/src/main/webapp/dictionary/concept.jsp | 58 +++++---- .../main/webapp/dictionary/conceptForm.jsp | 120 +++++++++--------- .../scripts/dictionary/conceptForm.js | 14 +- .../controller/ConceptFormControllerTest.java | 12 +- .../concept/ConceptFormControllerTest.java | 33 ----- 8 files changed, 225 insertions(+), 171 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 89c60780..c8b6e17d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -317,23 +317,30 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse void validateConceptReferenceRange(Concept concept, BindException errors) { if (concept.isNumeric()) { ConceptNumeric conceptNumeric = (ConceptNumeric) concept; + Set referenceRanges = conceptNumeric.getReferenceRanges(); + if (referenceRanges == null) { + return; + } + int index = 0; for (ConceptReferenceRange referenceRange : referenceRanges) { - + if (referenceRange.getUuid() == null) { - if (conceptNumeric.getHiAbsolute() != null && referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { + if (conceptNumeric.getHiAbsolute() != null + && referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { errors.pushNestedPath("referenceRanges[" + index + "].hiAbsolute"); errors.rejectValue("conceptSource", "error.value.outOfRange.high", - "High Absolute in reference range cannot be higher than high absolute of the concept"); + "High Absolute in reference range cannot be higher than high absolute of the concept"); errors.popNestedPath(); } - - if (conceptNumeric.getLowAbsolute() != null && referenceRange.getHiAbsolute() < conceptNumeric.getHiAbsolute()) { + + if (conceptNumeric.getLowAbsolute() != null + && referenceRange.getHiAbsolute() < conceptNumeric.getHiAbsolute()) { errors.pushNestedPath("referenceRanges[" + index + "].lowAbsolute"); errors.rejectValue("conceptSource", "error.value.outOfRange.low", - "Low Absolute in reference range cannot be lower than low absolute of the concept"); + "Low Absolute in reference range cannot be lower than low absolute of the concept"); errors.popNestedPath(); } } @@ -725,17 +732,23 @@ public Concept getConceptFromFormData() { * @param cn ConceptNumeric */ private void setConceptReferenceRanges(ConceptNumeric cn) { + if (this.referenceRanges == null) { + return; + } + for (ConceptReferenceRange referenceRange : this.referenceRanges) { - if (referenceRange != null) { - if (referenceRange.getUuid() != null) { - if (referenceRange.getUuid().isEmpty()) { - cn.getReferenceRanges().remove(referenceRange); - } - } else { - // Add new reference range - referenceRange.setConceptNumeric(cn); - cn.addReferenceRange(referenceRange); + if (referenceRange == null) { + continue; + } + + if (referenceRange.getUuid() != null) { + if (referenceRange.getUuid().isEmpty()) { + cn.getReferenceRanges().remove(referenceRange); } + } else { + // Add new reference range + referenceRange.setConceptNumeric(cn); + cn.addReferenceRange(referenceRange); } } } diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index fbd626fc..eb1b8c91 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,35 +319,37 @@ - - "> - - - - - style="display:none"> - - - - - - - - - - class='evenRow'> - - - - - - - + + + + - + + class='evenRow'> + + + + + + + + + +
"> + + + + style="display:none"> + + + + + + + - -
-
+ + +
diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index f8c07667..a531c1c6 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -820,6 +820,64 @@ + + + "/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ + + ${status.errorMessage} + +
+ +
+ + "/> diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index 7c434bc4..d8966064 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,35 +322,37 @@ - - "> - - - - - style="display:none"> - - - - - - - - - - class='evenRow'> - - - - - - - + + + + - + + class='evenRow'> + + + + + + + + + +
"> + + + + style="display:none"> + + + + + + + - -
-
+ + +
diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 660ae975..2ec187df 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -74,7 +74,7 @@ } $j(document).ready(function(){ - if(${fn:length(command.referenceRanges)} == 0) + if(${fn:length(command.conceptMappings)} == 0) $j(".hideableEle").hide(); }); @@ -821,66 +821,64 @@ - - - - "/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- - - ${status.errorMessage} - -
- -
- - -
+ + + "/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ + + ${status.errorMessage} + +
+ +
+ + diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index 3f488642..a0304573 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -169,13 +169,23 @@ customDatatypes.push("coded"); customDatatypes.push("complex"); function changeDatatype(obj) { + var selectedType = obj[obj.selectedIndex].text.toLowerCase(); + for (var i=0; i < customDatatypes.length; i++) { var row = document.getElementById(customDatatypes[i] + "DatatypeRow"); - if (obj[obj.selectedIndex].text.toLowerCase() == customDatatypes[i]) + if (selectedType == customDatatypes[i]) row.style.display = ""; else row.style.display = "none"; } + + var referenceRangeRow = document.getElementById("referenceRangeRow"); + + if (selectedType == "numeric") { + referenceRangeRow.style.display = ""; + } else { + referenceRangeRow.style.display = "none"; + } } function listKeyPress(from, to, delim, event) { @@ -504,8 +514,8 @@ function removeReferenceRangeElement(btn, key) { * the index of the row to be deleted */ function removeReferenceRangeElementByIndex(btn, index) { - var row = document.getElementById('row-' + index); removeParentElement(btn.parentNode); + var row = document.getElementById('row-' + index); document.getElementById('removeMarker-' + index).value = ""; } diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index d236ca62..754a20b5 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -1317,7 +1317,8 @@ public void shouldSetAttributesToVoidIfTheValueIsNotSet() throws Exception { } /** - * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, + * BindException) */ @Test public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() throws Exception { @@ -1344,7 +1345,8 @@ public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() thr } /** - * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, + * BindException) */ @Test public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() throws Exception { @@ -1379,7 +1381,8 @@ public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() th } /** - * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, + * BindException) */ @Test public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyData() throws Exception { @@ -1409,7 +1412,8 @@ public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyDa } /** - * @see ConceptFormController#onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException) + * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, + * BindException) */ @Test public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() throws Exception { diff --git a/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java index 7152ec2b..d4447b41 100644 --- a/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/concept/ConceptFormControllerTest.java @@ -15,7 +15,6 @@ import org.mockito.Mockito; import org.openmrs.ConceptMap; import org.openmrs.ConceptNumeric; -import org.openmrs.ConceptReferenceRange; import org.openmrs.web.controller.ConceptFormController; import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; @@ -58,36 +57,4 @@ public void ConceptFormBackingObject_shouldCopyNumericAttributes() { org.junit.Assert.assertEquals("ml", conceptFormBackingObject.getUnits()); } - @Test - public void testConceptFormBackingObject_shouldSetReferenceRangeAttributes() { - ConceptReferenceRange referenceRange = Mockito.mock(ConceptReferenceRange.class); - ConceptNumeric conceptNumeric = Mockito.mock(ConceptNumeric.class); - - Mockito.when(referenceRange.getHiAbsolute()).thenReturn(5.2); - Mockito.when(referenceRange.getLowAbsolute()).thenReturn(1.0); - - Mockito.when(referenceRange.getHiCritical()).thenReturn(4.1); - Mockito.when(referenceRange.getLowCritical()).thenReturn(2.1); - - Mockito.when(referenceRange.getLowNormal()).thenReturn(3.1); - Mockito.when(referenceRange.getHiNormal()).thenReturn(3.9); - - Mockito.when(referenceRange.getCriteria()).thenReturn(""); - - ConceptFormController controller = new ConceptFormController(); - ConceptReferenceRange conceptReferenceRange = controller.new ConceptFormBackingObject( - conceptNumeric).referenceRanges - .iterator().next(); - - org.junit.Assert.assertEquals(Double.valueOf(5.2), conceptReferenceRange.getHiAbsolute()); - org.junit.Assert.assertEquals(Double.valueOf(1.0), conceptReferenceRange.getLowAbsolute()); - - org.junit.Assert.assertEquals(Double.valueOf(4.1), conceptReferenceRange.getHiCritical()); - org.junit.Assert.assertEquals(Double.valueOf(2.1), conceptReferenceRange.getLowCritical()); - - org.junit.Assert.assertEquals(Double.valueOf(3.1), conceptReferenceRange.getLowNormal()); - org.junit.Assert.assertEquals(Double.valueOf(3.9), conceptReferenceRange.getHiNormal()); - - org.junit.Assert.assertEquals("", conceptReferenceRange.getCriteria()); - } } From 5fee0d84fbb11169040ea0d850ce43e4e9eff0b9 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sun, 8 Sep 2024 19:27:56 +0300 Subject: [PATCH 13/30] Creating a reflection object of reference range --- .../web/controller/ConceptFormController.java | 116 ++++++--- .../concept/ConceptReferenceRange.java | 226 ++++++++++++++++++ omod/src/main/resources/messages.properties | 8 +- .../webapp/admin/dictionary/conceptForm.jsp | 17 +- .../main/webapp/dictionary/conceptForm.jsp | 17 +- .../scripts/dictionary/conceptForm.js | 3 +- .../controller/ConceptFormControllerTest.java | 2 + 7 files changed, 341 insertions(+), 48 deletions(-) create mode 100644 omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index c8b6e17d..02261b83 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -41,7 +41,6 @@ import org.openmrs.ConceptMapType; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; -import org.openmrs.ConceptReferenceRange; import org.openmrs.ConceptReferenceTerm; import org.openmrs.ConceptSet; import org.openmrs.Drug; @@ -71,6 +70,7 @@ import org.openmrs.validator.ValidateUtil; import org.openmrs.web.WebConstants; import org.openmrs.web.attribute.WebAttributeUtil; +import org.openmrs.web.controller.concept.ConceptReferenceRange; import org.openmrs.web.controller.concept.ConceptReferenceTermWebValidator; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.beans.propertyeditors.CustomNumberEditor; @@ -318,38 +318,78 @@ void validateConceptReferenceRange(Concept concept, BindException errors) { if (concept.isNumeric()) { ConceptNumeric conceptNumeric = (ConceptNumeric) concept; - Set referenceRanges = conceptNumeric.getReferenceRanges(); + Set referenceRanges = conceptNumeric.getReferenceRanges(); if (referenceRanges == null) { return; } int index = 0; - for (ConceptReferenceRange referenceRange : referenceRanges) { + for (org.openmrs.ConceptReferenceRange referenceRange : referenceRanges) { - if (referenceRange.getUuid() == null) { - if (conceptNumeric.getHiAbsolute() != null - && referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { - errors.pushNestedPath("referenceRanges[" + index + "].hiAbsolute"); - errors.rejectValue("conceptSource", "error.value.outOfRange.high", - "High Absolute in reference range cannot be higher than high absolute of the concept"); - errors.popNestedPath(); + if (referenceRange.getId() == null) { + if (referenceRange.getHiAbsolute() == null) { + setRefernceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.high.absolute.value.required", + "Concept.referenceRanges.error.absolute.value.required"); + } else { + if (referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { + setRefernceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.highAbsolute.value.outOfRange", + "Concept.referenceRanges.error.absolute.value.invalid"); + } else if (referenceRange.getHiAbsolute() < conceptNumeric.getLowAbsolute()) { + setRefernceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.absolute.value.invalid", + "Concept.referenceRanges.error.absolute.value.invalid"); + } } - - if (conceptNumeric.getLowAbsolute() != null - && referenceRange.getHiAbsolute() < conceptNumeric.getHiAbsolute()) { - errors.pushNestedPath("referenceRanges[" + index + "].lowAbsolute"); - errors.rejectValue("conceptSource", "error.value.outOfRange.low", - "Low Absolute in reference range cannot be lower than low absolute of the concept"); - errors.popNestedPath(); + if (referenceRange.getLowAbsolute() == null) { + setRefernceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.low.absolute.value.required", + "Concept.referenceRanges.error.absolute.value.required"); + } else { + if (referenceRange.getLowAbsolute() < conceptNumeric.getLowAbsolute()) { + setRefernceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.lowAbsolute.value.outOfRange", + "Concept.referenceRanges.error.absolute.value.invalid"); + } else if (referenceRange.getLowAbsolute() > conceptNumeric.getHiAbsolute()) { + setRefernceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.absolute.value.invalid", + "Concept.referenceRanges.error.absolute.value.invalid"); + } } + + index++; } - - index++; } } } + public org.openmrs.web.controller.concept.ConceptReferenceRange mapToWebConceptReferenceRange( + org.openmrs.ConceptReferenceRange referenceRange) { + org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange = new ConceptReferenceRange(); + + webReferenceRange.setConceptReferenceRangeId(referenceRange.getConceptReferenceRangeId()); + webReferenceRange.setCriteria(referenceRange.getCriteria()); + webReferenceRange.setConceptNumeric(referenceRange.getConceptNumeric()); + webReferenceRange.setUuid(referenceRange.getUuid()); + webReferenceRange.setHiAbsolute(referenceRange.getHiAbsolute()); + webReferenceRange.setHiCritical(referenceRange.getHiCritical()); + webReferenceRange.setHiNormal(referenceRange.getHiNormal()); + webReferenceRange.setLowAbsolute(referenceRange.getLowAbsolute()); + webReferenceRange.setLowCritical(referenceRange.getLowCritical()); + webReferenceRange.setLowNormal(referenceRange.getLowNormal()); + + return webReferenceRange; + } + + private static void setRefernceRangeErrors(BindException errors, long index, String hiAbsolute, String errorCode, + String defaultMessage) { + errors.pushNestedPath("referenceRanges[" + index + "]"); + errors.rejectValue(hiAbsolute, errorCode, defaultMessage); + errors.popNestedPath(); + } + /** * @param concept * @param errors @@ -499,7 +539,7 @@ public class ConceptFormBackingObject { public Collection activeAttributes; - public List referenceRanges; + public List referenceRanges; /** * Default constructor must take in a Concept object to create itself @@ -560,8 +600,12 @@ public ConceptFormBackingObject(Concept concept) { this.displayPrecision = cn.getDisplayPrecision(); this.units = cn.getUnits(); - this.referenceRanges = ListUtils.lazyList(new ArrayList<>(cn.getReferenceRanges()), - FactoryUtils.instantiateFactory(ConceptReferenceRange.class)); + this.referenceRanges = ListUtils.lazyList( + new ArrayList<>(cn.getReferenceRanges() + .stream() + .map(ConceptFormController.this::mapToWebConceptReferenceRange) + .collect(Collectors.toList())), + FactoryUtils.instantiateFactory(org.openmrs.web.controller.concept.ConceptReferenceRange.class)); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; this.handlerKey = complex.getHandler(); @@ -736,23 +780,41 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { return; } - for (ConceptReferenceRange referenceRange : this.referenceRanges) { + for (org.openmrs.web.controller.concept.ConceptReferenceRange referenceRange : this.referenceRanges) { if (referenceRange == null) { continue; } - if (referenceRange.getUuid() != null) { - if (referenceRange.getUuid().isEmpty()) { - cn.getReferenceRanges().remove(referenceRange); + if (referenceRange.getId() != null) { + if (referenceRange.getId() <= 0) { + cn.getReferenceRanges().remove(mapToReferenceRange(referenceRange)); } } else { // Add new reference range referenceRange.setConceptNumeric(cn); - cn.addReferenceRange(referenceRange); + cn.addReferenceRange(mapToReferenceRange(referenceRange)); } } } + public org.openmrs.ConceptReferenceRange mapToReferenceRange( + org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange) { + org.openmrs.ConceptReferenceRange referenceRange = new org.openmrs.ConceptReferenceRange(); + + referenceRange.setConceptReferenceRangeId(webReferenceRange.getConceptReferenceRangeId()); + referenceRange.setCriteria(webReferenceRange.getCriteria()); + referenceRange.setConceptNumeric(webReferenceRange.getConceptNumeric()); + referenceRange.setUuid(webReferenceRange.getUuid()); + referenceRange.setHiAbsolute(webReferenceRange.getHiAbsolute()); + referenceRange.setHiCritical(webReferenceRange.getHiCritical()); + referenceRange.setHiNormal(webReferenceRange.getHiNormal()); + referenceRange.setLowAbsolute(webReferenceRange.getLowAbsolute()); + referenceRange.setLowCritical(webReferenceRange.getLowCritical()); + referenceRange.setLowNormal(webReferenceRange.getLowNormal()); + + return referenceRange; + } + /** * Builds a white-space separated list of concept ids belonging to a concept set * diff --git a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java new file mode 100644 index 00000000..1faf6b25 --- /dev/null +++ b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java @@ -0,0 +1,226 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.web.controller.concept; + +import org.openmrs.ConceptNumeric; + +/** + * This class is a reflection object of reference range A concept reference range is typically a + * range of a {@link ConceptNumeric} for certain factor(s) e.g. age, gender e.t.c. + * + * @since 1.17.0 + */ +public class ConceptReferenceRange { + + private Integer conceptReferenceRangeId; + + private String criteria; + + private ConceptNumeric conceptNumeric; + + private String uuid; + + private Double hiAbsolute; + + private Double hiCritical; + + private Double hiNormal; + + private Double lowAbsolute; + + private Double lowCritical; + + private Double lowNormal; + + public ConceptReferenceRange() { + } + + /** + * @return Returns the conceptRangeId. + */ + public Integer getConceptReferenceRangeId() { + return conceptReferenceRangeId; + } + + /** + * @param conceptReferenceRangeId The conceptReferenceRangeId to set. + */ + public void setConceptReferenceRangeId(Integer conceptReferenceRangeId) { + this.conceptReferenceRangeId = conceptReferenceRangeId; + } + + /** + * Returns the criteria of the conceptReferenceRange + * + * @return criteria the criteria + */ + public String getCriteria() { + return this.criteria; + } + + /** + * Sets the criteria of the conceptReferenceRange + * + * @param criteria the criteria to set + */ + public void setCriteria(String criteria) { + this.criteria = criteria; + } + + /** + * @return Returns the ConceptNumeric. + */ + public ConceptNumeric getConceptNumeric() { + return conceptNumeric; + } + + /** + * @param conceptNumeric concept to set. + */ + public void setConceptNumeric(ConceptNumeric conceptNumeric) { + this.conceptNumeric = conceptNumeric; + } + + /** + * @see org.openmrs.OpenmrsObject#getId() + */ + public Integer getId() { + return getConceptReferenceRangeId(); + } + + /** + * @see org.openmrs.OpenmrsObject#setId(java.lang.Integer) + */ + public void setId(Integer id) { + setConceptReferenceRangeId(id); + } + + /** + * @see org.openmrs.OpenmrsObject#getUuid() + */ + public String getUuid() { + return uuid; + } + + /** + * @see org.openmrs.OpenmrsObject#setUuid(java.lang.String) + */ + public void setUuid(String uuid) { + this.uuid = uuid; + } + + /** + * Returns high absolute value of the referenceRange + * + * @return hiAbsolute the high absolute value + */ + public Double getHiAbsolute() { + return this.hiAbsolute; + } + + /** + * Sets high absolute value of the referenceRange + * + * @param hiAbsolute high absolute value to set + */ + public void setHiAbsolute(Double hiAbsolute) { + this.hiAbsolute = hiAbsolute; + } + + /** + * Returns high critical value of the referenceRange + * + * @return the high critical value + */ + public Double getHiCritical() { + return this.hiCritical; + } + + /** + * Sets high critical value of the referenceRange + * + * @param hiCritical high critical value to set + */ + public void setHiCritical(Double hiCritical) { + this.hiCritical = hiCritical; + } + + /** + * Returns high normal value of the referenceRange + * + * @return the high normal value + */ + public Double getHiNormal() { + return this.hiNormal; + } + + /** + * Sets high normal value of the referenceRange + * + * @param hiNormal high normal value to set + */ + public void setHiNormal(Double hiNormal) { + this.hiNormal = hiNormal; + } + + /** + * Returns low absolute value of the referenceRange + * + * @return the low absolute value + */ + public Double getLowAbsolute() { + return this.lowAbsolute; + } + + /** + * Sets low absolute value of the referenceRange + * + * @param lowAbsolute low absolute value to set + */ + public void setLowAbsolute(Double lowAbsolute) { + this.lowAbsolute = lowAbsolute; + } + + /** + * Returns low critical value of the referenceRange + * + * @return the low critical value + */ + public Double getLowCritical() { + return this.lowCritical; + } + + /** + * Sets low critical value of the referenceRange + * + * @param lowCritical low critical value to set + */ + public void setLowCritical(Double lowCritical) { + this.lowCritical = lowCritical; + } + + /** + * Returns low normal value of the referenceRange + * + * @return the low normal value + */ + public Double getLowNormal() { + return this.lowNormal; + } + + /** + * Sets low normal value of the referenceRange + * + * @param lowNormal low normal value to set + */ + public void setLowNormal(Double lowNormal) { + this.lowNormal = lowNormal; + } +} diff --git a/omod/src/main/resources/messages.properties b/omod/src/main/resources/messages.properties index f7fc2ccd..81d94957 100644 --- a/omod/src/main/resources/messages.properties +++ b/omod/src/main/resources/messages.properties @@ -1,4 +1,10 @@ Concept.referenceRanges=Reference Ranges Concept.referenceRanges.criteria=Criteria Concept.referenceRanges.help=Defines reference ranges of this concept with a criteria -Concept.referenceRanges.add=Add a Reference Range \ No newline at end of file +Concept.referenceRanges.add=Add a Reference Range +Concept.referenceRanges.error.low.absolute.value.required=Low Absolute cannot be empty +Concept.referenceRanges.error.high.absolute.value.required=High Absolute cannot be empty +Concept.referenceRanges.error.absolute.value.required=Absolute value cannot be empty +Concept.referenceRanges.error.highAbsolute.value.outOfRange=High Absolute in reference range cannot be higher than high absolute value of the concept +Concept.referenceRanges.error.lowAbsolute.value.outOfRange=Low Absolute in reference range cannot be lower than low absolute value of the concept +Concept.referenceRanges.error.absolute.value.invalid=Invalid absolute value of reference range \ No newline at end of file diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index a531c1c6..f0e3889e 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -839,13 +839,13 @@ - - - - - - - + + + + + + + @@ -853,7 +853,7 @@ - + @@ -867,7 +867,6 @@ - diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 2ec187df..35dcd7f7 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -840,13 +840,13 @@ - - - - - - - + + + + + + + @@ -854,7 +854,7 @@ - + @@ -868,7 +868,6 @@ - diff --git a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js index a0304573..12ee568e 100644 --- a/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js +++ b/omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js @@ -485,7 +485,6 @@ function addReferenceRanges(initialSizeOfReferenceRanges) { } } - if(!$j("#headerRow").is(":visible")) $j(".referenceRangeHeader").show(); } @@ -517,7 +516,7 @@ function removeReferenceRangeElementByIndex(btn, index) { removeParentElement(btn.parentNode); var row = document.getElementById('row-' + index); - document.getElementById('removeMarker-' + index).value = ""; + document.getElementById('removeMarker-' + index).value = "0"; } function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){ diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index 754a20b5..ab62e483 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -1448,6 +1448,8 @@ public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() t @Test public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound() { ConceptNumeric conceptNumeric = new ConceptNumeric(); + conceptNumeric.setHiAbsolute(100.0); + conceptNumeric.setLowAbsolute(80.0); ConceptReferenceRange referenceRange = new ConceptReferenceRange(); referenceRange.setHiAbsolute(1100.0); referenceRange.setLowAbsolute(1.0); From cd19cda015244ce6aecea973e671f0ee67f80af2 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Tue, 10 Sep 2024 19:45:36 +0300 Subject: [PATCH 14/30] Using reflection to map reference ranges --- .../web/controller/ConceptFormController.java | 143 +++++------------- .../web/controller/ConceptFormValidator.java | 84 +++++++++- .../concept/ConceptReferenceRange.java | 4 +- .../controller/mappper/ConceptFormMapper.java | 105 +++++++++++++ .../controller/ConceptFormControllerTest.java | 63 ++++++-- pom.xml | 2 +- 6 files changed, 278 insertions(+), 123 deletions(-) create mode 100644 omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 02261b83..6413f911 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -9,6 +9,8 @@ */ package org.openmrs.web.controller; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -21,7 +23,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -72,6 +73,7 @@ import org.openmrs.web.attribute.WebAttributeUtil; import org.openmrs.web.controller.concept.ConceptReferenceRange; import org.openmrs.web.controller.concept.ConceptReferenceTermWebValidator; +import org.openmrs.web.controller.mappper.ConceptFormMapper; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.context.support.MessageSourceAccessor; @@ -273,7 +275,7 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse validateConceptUsesPersistedObjects(concept, errors); - validateConceptReferenceRange(concept, errors); + new ConceptFormValidator().validateConceptReferenceRange(concept, errors); if (!errors.hasErrors()) { if (action.equals(msa.getMessage("Concept.cancel"))) { @@ -314,82 +316,6 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse return new ModelAndView(new RedirectView(getFormView())); } - void validateConceptReferenceRange(Concept concept, BindException errors) { - if (concept.isNumeric()) { - ConceptNumeric conceptNumeric = (ConceptNumeric) concept; - - Set referenceRanges = conceptNumeric.getReferenceRanges(); - - if (referenceRanges == null) { - return; - } - - int index = 0; - for (org.openmrs.ConceptReferenceRange referenceRange : referenceRanges) { - - if (referenceRange.getId() == null) { - if (referenceRange.getHiAbsolute() == null) { - setRefernceRangeErrors(errors, index, "hiAbsolute", - "Concept.referenceRanges.error.high.absolute.value.required", - "Concept.referenceRanges.error.absolute.value.required"); - } else { - if (referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { - setRefernceRangeErrors(errors, index, "hiAbsolute", - "Concept.referenceRanges.error.highAbsolute.value.outOfRange", - "Concept.referenceRanges.error.absolute.value.invalid"); - } else if (referenceRange.getHiAbsolute() < conceptNumeric.getLowAbsolute()) { - setRefernceRangeErrors(errors, index, "hiAbsolute", - "Concept.referenceRanges.error.absolute.value.invalid", - "Concept.referenceRanges.error.absolute.value.invalid"); - } - } - if (referenceRange.getLowAbsolute() == null) { - setRefernceRangeErrors(errors, index, "lowAbsolute", - "Concept.referenceRanges.error.low.absolute.value.required", - "Concept.referenceRanges.error.absolute.value.required"); - } else { - if (referenceRange.getLowAbsolute() < conceptNumeric.getLowAbsolute()) { - setRefernceRangeErrors(errors, index, "lowAbsolute", - "Concept.referenceRanges.error.lowAbsolute.value.outOfRange", - "Concept.referenceRanges.error.absolute.value.invalid"); - } else if (referenceRange.getLowAbsolute() > conceptNumeric.getHiAbsolute()) { - setRefernceRangeErrors(errors, index, "lowAbsolute", - "Concept.referenceRanges.error.absolute.value.invalid", - "Concept.referenceRanges.error.absolute.value.invalid"); - } - } - - index++; - } - } - } - } - - public org.openmrs.web.controller.concept.ConceptReferenceRange mapToWebConceptReferenceRange( - org.openmrs.ConceptReferenceRange referenceRange) { - org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange = new ConceptReferenceRange(); - - webReferenceRange.setConceptReferenceRangeId(referenceRange.getConceptReferenceRangeId()); - webReferenceRange.setCriteria(referenceRange.getCriteria()); - webReferenceRange.setConceptNumeric(referenceRange.getConceptNumeric()); - webReferenceRange.setUuid(referenceRange.getUuid()); - webReferenceRange.setHiAbsolute(referenceRange.getHiAbsolute()); - webReferenceRange.setHiCritical(referenceRange.getHiCritical()); - webReferenceRange.setHiNormal(referenceRange.getHiNormal()); - webReferenceRange.setLowAbsolute(referenceRange.getLowAbsolute()); - webReferenceRange.setLowCritical(referenceRange.getLowCritical()); - webReferenceRange.setLowNormal(referenceRange.getLowNormal()); - - return webReferenceRange; - } - - private static void setRefernceRangeErrors(BindException errors, long index, String hiAbsolute, String errorCode, - String defaultMessage) { - errors.pushNestedPath("referenceRanges[" + index + "]"); - errors.rejectValue(hiAbsolute, errorCode, defaultMessage); - errors.popNestedPath(); - } - /** * @param concept * @param errors @@ -601,11 +527,8 @@ public ConceptFormBackingObject(Concept concept) { this.units = cn.getUnits(); this.referenceRanges = ListUtils.lazyList( - new ArrayList<>(cn.getReferenceRanges() - .stream() - .map(ConceptFormController.this::mapToWebConceptReferenceRange) - .collect(Collectors.toList())), - FactoryUtils.instantiateFactory(org.openmrs.web.controller.concept.ConceptReferenceRange.class)); + new ArrayList<>(new ConceptFormMapper().mapToWebReferenceRanges(cn)), + FactoryUtils.instantiateFactory(ConceptReferenceRange.class)); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; this.handlerKey = complex.getHandler(); @@ -770,16 +693,17 @@ public Concept getConceptFromFormData() { } /** - * This method adds new reference ranges to concept numeric. If an existing reference range - * was removed, then we remove it from concept numeric + * This method sets reference ranges to concept numeric. If an existing reference range was + * removed, then we remove it from concept numeric. * * @param cn ConceptNumeric + * + * @since 1.17.0 */ private void setConceptReferenceRanges(ConceptNumeric cn) { if (this.referenceRanges == null) { return; } - for (org.openmrs.web.controller.concept.ConceptReferenceRange referenceRange : this.referenceRanges) { if (referenceRange == null) { continue; @@ -787,38 +711,45 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { if (referenceRange.getId() != null) { if (referenceRange.getId() <= 0) { - cn.getReferenceRanges().remove(mapToReferenceRange(referenceRange)); + updateConceptReferenceRange(referenceRange, cn, "removeReferenceRange"); } } else { // Add new reference range referenceRange.setConceptNumeric(cn); - cn.addReferenceRange(mapToReferenceRange(referenceRange)); + updateConceptReferenceRange(referenceRange, cn, "addReferenceRange"); } } } - - public org.openmrs.ConceptReferenceRange mapToReferenceRange( - org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange) { - org.openmrs.ConceptReferenceRange referenceRange = new org.openmrs.ConceptReferenceRange(); - - referenceRange.setConceptReferenceRangeId(webReferenceRange.getConceptReferenceRangeId()); - referenceRange.setCriteria(webReferenceRange.getCriteria()); - referenceRange.setConceptNumeric(webReferenceRange.getConceptNumeric()); - referenceRange.setUuid(webReferenceRange.getUuid()); - referenceRange.setHiAbsolute(webReferenceRange.getHiAbsolute()); - referenceRange.setHiCritical(webReferenceRange.getHiCritical()); - referenceRange.setHiNormal(webReferenceRange.getHiNormal()); - referenceRange.setLowAbsolute(webReferenceRange.getLowAbsolute()); - referenceRange.setLowCritical(webReferenceRange.getLowCritical()); - referenceRange.setLowNormal(webReferenceRange.getLowNormal()); - - return referenceRange; - } + + /** + * This method updates concept reference range in concept numeric e.g. adding a reference range + * + * @param webReferenceRange the reference range + * @param cn ConceptNumeric + * @param invocationMethod method in ConceptNumeric to invoke + * + * @since 1.17.0 + */ + public void updateConceptReferenceRange( + org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange, + ConceptNumeric cn, + String invocationMethod) { + try { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + Object referenceRange = new ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, referenceRangeClass); + Method method = ConceptNumeric.class.getMethod(invocationMethod, referenceRangeClass); + method.invoke(cn, referenceRange); + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { + logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + } + } /** * Builds a white-space separated list of concept ids belonging to a concept set * * @return white-space separated list + * + * @since 1.17.0 */ public String getSetElements() { StringBuilder result = new StringBuilder(); diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index 8276524b..85701cb8 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -10,16 +10,22 @@ package org.openmrs.web.controller; import java.util.HashSet; +import java.util.List; import java.util.Locale; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.openmrs.Concept; import org.openmrs.ConceptMap; import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; import org.openmrs.api.context.Context; import org.openmrs.web.controller.ConceptFormController.ConceptFormBackingObject; +import org.openmrs.web.controller.concept.ConceptReferenceRange; +import org.openmrs.web.controller.mappper.ConceptFormMapper; +import org.springframework.validation.BindException; import org.springframework.validation.Errors; import org.springframework.validation.Validator; @@ -112,5 +118,81 @@ else if (backingObject.getNamesByLocale().get(locale).getConceptNameId() != null errors.rejectValue("concept", sb.toString()); } } - + + /** + * Validates reference range fields + * + * @param concept concept + * @param errors errors + * + * @since 1.17.0 + */ + public void validateConceptReferenceRange(Concept concept, BindException errors) { + if (concept.isNumeric()) { + ConceptNumeric conceptNumeric = (ConceptNumeric) concept; + + List referenceRanges = new ConceptFormMapper().mapToWebReferenceRanges(conceptNumeric); + + if (referenceRanges == null || referenceRanges.isEmpty()) { + return; + } + + int index = 0; + for (ConceptReferenceRange referenceRange : referenceRanges) { + + if (referenceRange.getId() == null) { + if (referenceRange.getHiAbsolute() == null) { + setReferenceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.high.absolute.value.required", + "Concept.referenceRanges.error.absolute.value.required"); + } else { + if (referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { + setReferenceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.highAbsolute.value.outOfRange", + "Concept.referenceRanges.error.absolute.value.invalid"); + } else if (referenceRange.getHiAbsolute() < conceptNumeric.getLowAbsolute()) { + setReferenceRangeErrors(errors, index, "hiAbsolute", + "Concept.referenceRanges.error.absolute.value.invalid", + "Concept.referenceRanges.error.absolute.value.invalid"); + } + } + if (referenceRange.getLowAbsolute() == null) { + setReferenceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.low.absolute.value.required", + "Concept.referenceRanges.error.absolute.value.required"); + } else { + if (referenceRange.getLowAbsolute() < conceptNumeric.getLowAbsolute()) { + setReferenceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.lowAbsolute.value.outOfRange", + "Concept.referenceRanges.error.absolute.value.invalid"); + } else if (referenceRange.getLowAbsolute() > conceptNumeric.getHiAbsolute()) { + setReferenceRangeErrors(errors, index, "lowAbsolute", + "Concept.referenceRanges.error.absolute.value.invalid", + "Concept.referenceRanges.error.absolute.value.invalid"); + } + } + + index++; + } + } + } + } + + /** + * Set Reference Range Errors + * + * @param errors BindException + * @param index index of referenceRange row + * @param field field of the reference range + * @param errorCode error code + * @param defaultMessage default message + * + * @since 1.17.0 + */ + private static void setReferenceRangeErrors(BindException errors, long index, String field, String errorCode, + String defaultMessage) { + errors.pushNestedPath("referenceRanges[" + index + "]"); + errors.rejectValue(field, errorCode, defaultMessage); + errors.popNestedPath(); + } } diff --git a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java index 1faf6b25..08388bdd 100644 --- a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java +++ b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java @@ -12,8 +12,8 @@ import org.openmrs.ConceptNumeric; /** - * This class is a reflection object of reference range A concept reference range is typically a - * range of a {@link ConceptNumeric} for certain factor(s) e.g. age, gender e.t.c. + * This class is a view object of reference range. A concept reference range is typically a range of + * a {@link ConceptNumeric} for certain factor(s) e.g. age, gender e.t.c. * * @since 1.17.0 */ diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java new file mode 100644 index 00000000..c8f0cef6 --- /dev/null +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -0,0 +1,105 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.web.controller.mappper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.ConceptNumeric; +import org.openmrs.web.controller.concept.ConceptReferenceRange; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * This class maps the web-based concept attributes to their corresponding internal concepts and + * vice versa. + * + * @since 1.17.0 + */ +public class ConceptFormMapper { + + protected final Log logger = LogFactory.getLog(getClass()); + + /** + * Maps reference range in openMRS core to web's reference range + * + * @param webReferenceRange webReferenceRange + * @param cn ConceptNumeric + * @param referenceRangeClass reference range class + * + * @return reference range + */ + public Object mapToConceptReferenceRange( + ConceptReferenceRange webReferenceRange, + ConceptNumeric cn, + Class referenceRangeClass) { + + try { + Object referenceRange = referenceRangeClass.getDeclaredConstructor().newInstance(); + + referenceRangeClass.getMethod("setCriteria", String.class).invoke(referenceRange, webReferenceRange.getCriteria()); + referenceRangeClass.getMethod("setConceptNumeric", ConceptNumeric.class).invoke(referenceRange, cn); + referenceRangeClass.getMethod("setUuid", String.class).invoke(referenceRange, webReferenceRange.getUuid()); + referenceRangeClass.getMethod("setHiAbsolute", Double.class).invoke(referenceRange, webReferenceRange.getHiAbsolute()); + referenceRangeClass.getMethod("setHiCritical", Double.class).invoke(referenceRange, webReferenceRange.getHiCritical()); + referenceRangeClass.getMethod("setHiNormal", Double.class).invoke(referenceRange, webReferenceRange.getHiNormal()); + referenceRangeClass.getMethod("setLowAbsolute", Double.class).invoke(referenceRange, webReferenceRange.getLowAbsolute()); + referenceRangeClass.getMethod("setLowCritical", Double.class).invoke(referenceRange, webReferenceRange.getLowCritical()); + referenceRangeClass.getMethod("setLowNormal", Double.class).invoke(referenceRange, webReferenceRange.getLowNormal()); + referenceRangeClass.getMethod("setConceptReferenceRangeId", Integer.class).invoke(referenceRange, webReferenceRange.getConceptReferenceRangeId()); + + return referenceRange; + + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException exception) { + logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + } + return null; + } + + /** + * Maps web's reference range to reference range in openMRS core + * + * @param cn ConceptNumeric + * @return list of reference range + */ + public List mapToWebReferenceRanges(ConceptNumeric cn) { + List webReferenceRanges = new ArrayList<>(); + + try { + Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges"); + Object referenceRanges = getReferenceRangesMethod.invoke(cn); + System.out.println("In mapper:- getReferenceRangesMethod name = " + getReferenceRangesMethod); + + for (Object referenceRange : (Set) referenceRanges) { + ConceptReferenceRange webReferenceRange = new ConceptReferenceRange(); + + webReferenceRange.setConceptReferenceRangeId((Integer) referenceRange.getClass().getMethod("getConceptReferenceRangeId").invoke(referenceRange)); + webReferenceRange.setUuid((String) referenceRange.getClass().getMethod("getUuid").invoke(referenceRange)); + webReferenceRange.setCriteria((String) referenceRange.getClass().getMethod("getCriteria").invoke(referenceRange)); + webReferenceRange.setHiAbsolute((Double) referenceRange.getClass().getMethod("getHiAbsolute").invoke(referenceRange)); + webReferenceRange.setHiCritical((Double) referenceRange.getClass().getMethod("getHiCritical").invoke(referenceRange)); + webReferenceRange.setHiNormal((Double) referenceRange.getClass().getMethod("getHiNormal").invoke(referenceRange)); + webReferenceRange.setLowAbsolute((Double) referenceRange.getClass().getMethod("getLowAbsolute").invoke(referenceRange)); + webReferenceRange.setLowCritical((Double) referenceRange.getClass().getMethod("getLowCritical").invoke(referenceRange)); + webReferenceRange.setLowNormal((Double) referenceRange.getClass().getMethod("getLowNormal").invoke(referenceRange)); + webReferenceRange.setConceptNumeric((ConceptNumeric) referenceRange.getClass().getMethod("getConceptNumeric").invoke(referenceRange)); + + webReferenceRanges.add(webReferenceRange); + } + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + logger.error("Failed to map to web reference range: Exception: " + e.getMessage(), e); + } + + return webReferenceRanges; + } +} diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index ab62e483..08f0ded6 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -19,8 +19,11 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collection; import java.util.Locale; +import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,7 +41,6 @@ import org.openmrs.ConceptMapType; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; -import org.openmrs.ConceptReferenceRange; import org.openmrs.ConceptReferenceTerm; import org.openmrs.ConceptReferenceTermMap; import org.openmrs.ConceptSource; @@ -50,6 +52,8 @@ import org.openmrs.util.LocaleUtility; import org.openmrs.util.OpenmrsConstants; import org.openmrs.web.controller.ConceptFormController.ConceptFormBackingObject; +import org.openmrs.web.controller.concept.ConceptReferenceRange; +import org.openmrs.web.controller.mappper.ConceptFormMapper; import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; import org.openmrs.web.test.WebTestHelper; import org.openmrs.web.test.WebTestHelper.Response; @@ -1326,7 +1330,7 @@ public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() thr ConceptNumeric conceptNumeric = cs.getConceptNumeric(4090); assertNotNull(conceptNumeric); - int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); MockHttpServletRequest mockRequest = new MockHttpServletRequest(); @@ -1340,8 +1344,7 @@ public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() thr ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); - - assertEquals(initialConceptMappingCount + 1, cs.getConceptReferenceRangesByConceptId(conceptNumeric.getConceptId())); + assertEquals(initialConceptMappingCount + 1, getReferenceRangesByConceptId(cs, conceptNumeric.getConceptId())); } /** @@ -1377,7 +1380,11 @@ public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() th Concept createdConcept = cs.getConceptByName(conceptName); assertNotNull(createdConcept); assertTrue(createdConcept instanceof ConceptNumeric); - Assert.assertEquals(1, ((ConceptNumeric) createdConcept).getReferenceRanges().size()); + + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges", referenceRangeClass); + Set listOfReferenceRanges = (Set) getReferenceRangesMethod.invoke(createdConcept, null); + Assert.assertEquals(1, listOfReferenceRanges.size()); } /** @@ -1391,7 +1398,7 @@ public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyDa int conceptId = 4090; ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); assertNotNull(conceptNumeric); - int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); MockHttpServletRequest mockRequest = new MockHttpServletRequest(); @@ -1408,7 +1415,7 @@ public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyDa assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); - assertEquals(initialConceptMappingCount, cs.getConceptReferenceRangesByConceptId(conceptId).size()); + assertEquals(initialConceptMappingCount, getReferenceRangesByConceptId(cs, conceptId).size()); } /** @@ -1423,7 +1430,7 @@ public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() t // make sure the concept already exists and has some concept mappings ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); assertNotNull(conceptNumeric); - int initialConceptMappingCount = conceptNumeric.getReferenceRanges().size(); + int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); assertTrue(initialConceptMappingCount > 0); ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); @@ -1433,17 +1440,17 @@ public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() t mockRequest.setMethod("POST"); mockRequest.setParameter("action", ""); mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); - mockRequest.setParameter("referenceRanges[0].uuid", ""); + mockRequest.setParameter("referenceRanges[0].id", "0"); ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); - assertEquals(initialConceptMappingCount - 1, cs.getConceptReferenceRangesByConceptId(conceptId).size()); + assertEquals(initialConceptMappingCount - 1, getReferenceRangesByConceptId(cs, conceptId).size()); } /** - * @see ConceptFormController#validateConceptReferenceRange(Concept, BindException) + * @see ConceptFormValidator#validateConceptReferenceRange(Concept, BindException) */ @Test public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound() { @@ -1453,11 +1460,41 @@ public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideC ConceptReferenceRange referenceRange = new ConceptReferenceRange(); referenceRange.setHiAbsolute(1100.0); referenceRange.setLowAbsolute(1.0); - conceptNumeric.addReferenceRange(referenceRange); + updateConceptReferenceRange(referenceRange, conceptNumeric, "addReferenceRange"); BindException errors = new BindException(conceptNumeric, "conceptNumeric"); - new ConceptFormController().validateConceptReferenceRange(conceptNumeric, errors); + new ConceptFormValidator().validateConceptReferenceRange(conceptNumeric, errors); Assert.assertEquals(1, errors.getErrorCount()); assertTrue(errors.hasFieldErrors("referenceRanges[0].hiAbsolute")); assertTrue(errors.hasFieldErrors("referenceRanges[0].lowAbsolute")); } + + private void updateConceptReferenceRange( + org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange, + ConceptNumeric cn, + String invocationMethod) { + + try { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + Object referenceRange = new ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, referenceRangeClass); + Method method = ConceptNumeric.class.getMethod(invocationMethod, referenceRangeClass); + method.invoke(cn, referenceRange); + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { + logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + } + } + + private static Set getReferenceRangesByConceptId(ConceptService cs, int conceptId) throws NoSuchMethodException, + IllegalAccessException, InvocationTargetException, ClassNotFoundException { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + Method getConceptReferenceRangesByConceptIdMethod = ConceptService.class.getMethod( + "getConceptReferenceRangesByConceptId", referenceRangeClass); + return (Set) getConceptReferenceRangesByConceptIdMethod.invoke(cs, conceptId); + } + + private static Set getReferenceRangesFromConceptNumeric(ConceptNumeric conceptNumeric) throws NoSuchMethodException, + IllegalAccessException, InvocationTargetException, ClassNotFoundException { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges", referenceRangeClass); + return (Set) getReferenceRangesMethod.invoke(conceptNumeric, null); + } } diff --git a/pom.xml b/pom.xml index e5878b34..e861ba92 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 2.7.0-SNAPSHOT + 2.0.0 UTF-8 1.8 From 46e9cdfc43a2e825991f78da1e11499b318448fb Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 11 Sep 2024 12:15:01 +0300 Subject: [PATCH 15/30] Updating reflection in tests --- .../controller/ConceptFormControllerTest.java | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index 08f0ded6..7b82d53f 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -1319,11 +1319,14 @@ public void shouldSetAttributesToVoidIfTheValueIsNotSet() throws Exception { Assert.assertTrue(((ConceptAttribute) (concept.getAttributes().toArray()[0])).getVoided()); Assert.assertFalse(errors.hasErrors()); } - - /** - * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, - * BindException) - */ + + /** To be uncommented when the openmrs-core version in this module is ultimately changed to 2.7.0 or above + + +// /** +// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, +// * BindException) +// / @Test public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() throws Exception { ConceptService cs = Context.getConceptService(); @@ -1347,10 +1350,10 @@ public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() thr assertEquals(initialConceptMappingCount + 1, getReferenceRangesByConceptId(cs, conceptNumeric.getConceptId())); } - /** - * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, - * BindException) - */ +// /** +// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, +// * BindException) +// / @Test public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() throws Exception { ConceptService cs = Context.getConceptService(); @@ -1387,10 +1390,10 @@ public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() th Assert.assertEquals(1, listOfReferenceRanges.size()); } - /** - * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, - * BindException) - */ +// /** +// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, +// * BindException) +// / @Test public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyData() throws Exception { ConceptService cs = Context.getConceptService(); @@ -1418,10 +1421,10 @@ public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyDa assertEquals(initialConceptMappingCount, getReferenceRangesByConceptId(cs, conceptId).size()); } - /** - * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, - * BindException) - */ +// /** +// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, +// * BindException) +// / @Test public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() throws Exception { ConceptService cs = Context.getConceptService(); @@ -1449,9 +1452,9 @@ public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() t assertEquals(initialConceptMappingCount - 1, getReferenceRangesByConceptId(cs, conceptId).size()); } - /** - * @see ConceptFormValidator#validateConceptReferenceRange(Concept, BindException) - */ +// /** +// * @see ConceptFormValidator#validateConceptReferenceRange(Concept, BindException) +// / @Test public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound() { ConceptNumeric conceptNumeric = new ConceptNumeric(); @@ -1460,7 +1463,7 @@ public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideC ConceptReferenceRange referenceRange = new ConceptReferenceRange(); referenceRange.setHiAbsolute(1100.0); referenceRange.setLowAbsolute(1.0); - updateConceptReferenceRange(referenceRange, conceptNumeric, "addReferenceRange"); + updateConceptReferenceRange(referenceRange, conceptNumeric); BindException errors = new BindException(conceptNumeric, "conceptNumeric"); new ConceptFormValidator().validateConceptReferenceRange(conceptNumeric, errors); Assert.assertEquals(1, errors.getErrorCount()); @@ -1469,32 +1472,31 @@ public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideC } private void updateConceptReferenceRange( - org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange, - ConceptNumeric cn, - String invocationMethod) { + ConceptReferenceRange webReferenceRange, + ConceptNumeric cn) { try { Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); Object referenceRange = new ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, referenceRangeClass); - Method method = ConceptNumeric.class.getMethod(invocationMethod, referenceRangeClass); - method.invoke(cn, referenceRange); + Method addReferenceRangeMethod = ConceptNumeric.class.getMethod("addReferenceRange", referenceRangeClass); + addReferenceRangeMethod.invoke(cn, referenceRange); } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); } } private static Set getReferenceRangesByConceptId(ConceptService cs, int conceptId) throws NoSuchMethodException, - IllegalAccessException, InvocationTargetException, ClassNotFoundException { - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + IllegalAccessException, InvocationTargetException { Method getConceptReferenceRangesByConceptIdMethod = ConceptService.class.getMethod( - "getConceptReferenceRangesByConceptId", referenceRangeClass); + "getConceptReferenceRangesByConceptId", Integer.class); return (Set) getConceptReferenceRangesByConceptIdMethod.invoke(cs, conceptId); } private static Set getReferenceRangesFromConceptNumeric(ConceptNumeric conceptNumeric) throws NoSuchMethodException, - IllegalAccessException, InvocationTargetException, ClassNotFoundException { - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges", referenceRangeClass); - return (Set) getReferenceRangesMethod.invoke(conceptNumeric, null); + IllegalAccessException, InvocationTargetException { + Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges"); + return (Set) getReferenceRangesMethod.invoke(conceptNumeric); } + + */ } From a43a3911bc3e7fb5a41b91c60049464cc7a7a038 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 11 Sep 2024 17:20:17 +0300 Subject: [PATCH 16/30] Code refactor --- .../web/controller/ConceptFormController.java | 10 +++--- .../web/controller/ConceptFormValidator.java | 11 +++--- .../controller/mappper/ConceptFormMapper.java | 35 +++++++++---------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 6413f911..04beb8fb 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -697,7 +697,6 @@ public Concept getConceptFromFormData() { * removed, then we remove it from concept numeric. * * @param cn ConceptNumeric - * * @since 1.17.0 */ private void setConceptReferenceRanges(ConceptNumeric cn) { @@ -720,14 +719,14 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { } } } - + /** - * This method updates concept reference range in concept numeric e.g. adding a reference range - * + * This method updates concept reference range in concept numeric e.g. adding a reference + * range + * * @param webReferenceRange the reference range * @param cn ConceptNumeric * @param invocationMethod method in ConceptNumeric to invoke - * * @since 1.17.0 */ public void updateConceptReferenceRange( @@ -748,7 +747,6 @@ public void updateConceptReferenceRange( * Builds a white-space separated list of concept ids belonging to a concept set * * @return white-space separated list - * * @since 1.17.0 */ public String getSetElements() { diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index 85701cb8..5b0a72cb 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -118,13 +118,12 @@ else if (backingObject.getNamesByLocale().get(locale).getConceptNameId() != null errors.rejectValue("concept", sb.toString()); } } - + /** * Validates reference range fields - * + * * @param concept concept * @param errors errors - * * @since 1.17.0 */ public void validateConceptReferenceRange(Concept concept, BindException errors) { @@ -177,10 +176,10 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) } } } - + /** * Set Reference Range Errors - * + * * @param errors BindException * @param index index of referenceRange row * @param field field of the reference range @@ -190,7 +189,7 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) * @since 1.17.0 */ private static void setReferenceRangeErrors(BindException errors, long index, String field, String errorCode, - String defaultMessage) { + String defaultMessage) { errors.pushNestedPath("referenceRanges[" + index + "]"); errors.rejectValue(field, errorCode, defaultMessage); errors.popNestedPath(); diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java index c8f0cef6..9408ef0f 100644 --- a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -23,22 +23,21 @@ /** * This class maps the web-based concept attributes to their corresponding internal concepts and * vice versa. - * + * * @since 1.17.0 */ public class ConceptFormMapper { protected final Log logger = LogFactory.getLog(getClass()); - - /** - * Maps reference range in openMRS core to web's reference range - * - * @param webReferenceRange webReferenceRange - * @param cn ConceptNumeric - * @param referenceRangeClass reference range class - * - * @return reference range - */ + + /** + * Maps reference range in openMRS core to web's reference range + * + * @param webReferenceRange webReferenceRange + * @param cn ConceptNumeric + * @param referenceRangeClass reference range class + * @return reference range + */ public Object mapToConceptReferenceRange( ConceptReferenceRange webReferenceRange, ConceptNumeric cn, @@ -65,13 +64,13 @@ public Object mapToConceptReferenceRange( } return null; } - - /** - * Maps web's reference range to reference range in openMRS core - * - * @param cn ConceptNumeric - * @return list of reference range - */ + + /** + * Maps web's reference range to reference range in openMRS core + * + * @param cn ConceptNumeric + * @return list of reference range + */ public List mapToWebReferenceRanges(ConceptNumeric cn) { List webReferenceRanges = new ArrayList<>(); From a1c1f4d92ab2127d772a7f29b746211b687297d1 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sat, 14 Sep 2024 19:32:12 +0300 Subject: [PATCH 17/30] Update reference ranges --- .../web/controller/ConceptFormController.java | 84 +++-- .../web/controller/ConceptFormValidator.java | 1 - .../controller/mappper/ConceptFormMapper.java | 9 +- .../main/webapp/admin/dictionary/concept.jsp | 4 +- omod/src/main/webapp/dictionary/concept.jsp | 4 +- .../main/webapp/dictionary/conceptForm.jsp | 1 - .../controller/ConceptFormControllerTest.java | 295 +++++++----------- pom.xml | 2 +- 8 files changed, 190 insertions(+), 210 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 04beb8fb..502e5740 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import javax.servlet.ServletException; @@ -703,46 +704,91 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { if (this.referenceRanges == null) { return; } - for (org.openmrs.web.controller.concept.ConceptReferenceRange referenceRange : this.referenceRanges) { + for (ConceptReferenceRange referenceRange : this.referenceRanges) { if (referenceRange == null) { continue; } if (referenceRange.getId() != null) { if (referenceRange.getId() <= 0) { - updateConceptReferenceRange(referenceRange, cn, "removeReferenceRange"); + try { + Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange( + referenceRange, cn); + setMethodValue(cn, "removeReferenceRange", platformReferenceRange); + } + catch (Exception exception) { + logger.error("Failed to remove reference range: Exception: " + exception.getMessage(), exception); + } + } else { + updateReferenceRange(cn, referenceRange); } } else { - // Add new reference range referenceRange.setConceptNumeric(cn); - updateConceptReferenceRange(referenceRange, cn, "addReferenceRange"); + try { + Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange(referenceRange, + cn); + setMethodValue(cn, "addReferenceRange", platformReferenceRange); + } + catch (Exception exception) { + logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + } } } } /** - * This method updates concept reference range in concept numeric e.g. adding a reference - * range + * This method updates concept reference range if a field value has changed. * - * @param webReferenceRange the reference range - * @param cn ConceptNumeric - * @param invocationMethod method in ConceptNumeric to invoke * @since 1.17.0 */ - public void updateConceptReferenceRange( - org.openmrs.web.controller.concept.ConceptReferenceRange webReferenceRange, - ConceptNumeric cn, - String invocationMethod) { + public void updateReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenceRange) { try { - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - Object referenceRange = new ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, referenceRangeClass); - Method method = ConceptNumeric.class.getMethod(invocationMethod, referenceRangeClass); - method.invoke(cn, referenceRange); - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { + Method getReferenceRangesMethod = cn.getClass().getMethod("getReferenceRanges"); + Set referenceRanges = (Set) getReferenceRangesMethod.invoke(cn); + + for (Object rr : referenceRanges) { + Method getIdMethod = rr.getClass().getMethod("getId"); + Object idValue = getIdMethod.invoke(rr); + + if (Objects.equals(idValue, referenceRange.getId())) { + + if (!referenceRange.getCriteria().equals(getMethodValue(rr, "getCriteria")) || + !Objects.equals(referenceRange.getHiAbsolute(), getMethodValue(rr, "getHiAbsolute")) || + !Objects.equals(referenceRange.getHiCritical(), getMethodValue(rr, "getHiCritical")) || + !Objects.equals(referenceRange.getHiNormal(), getMethodValue(rr, "getHiNormal")) || + !Objects.equals(referenceRange.getLowAbsolute(), getMethodValue(rr, "getLowAbsolute")) || + !Objects.equals(referenceRange.getLowCritical(), getMethodValue(rr, "getLowCritical")) || + !Objects.equals(referenceRange.getLowNormal(), getMethodValue(rr, "getLowNormal"))) { + + setMethodValue(rr, "setHiAbsolute", referenceRange.getHiAbsolute()); + setMethodValue(rr, "setHiCritical", referenceRange.getHiCritical()); + setMethodValue(rr, "setHiNormal", referenceRange.getHiNormal()); + setMethodValue(rr, "setLowAbsolute", referenceRange.getLowAbsolute()); + setMethodValue(rr, "setLowCritical", referenceRange.getLowCritical()); + setMethodValue(rr, "setLowNormal", referenceRange.getLowNormal()); + setMethodValue(rr, "setCriteria", referenceRange.getCriteria()); + } + break; + } + } + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | + ClassNotFoundException exception) { + logger.error("Failed to update reference range: Exception: " + exception.getMessage(), exception); + } catch (Exception exception) { logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); - } + } } + private Object getMethodValue(Object obj, String methodName) throws Exception { + Method method = obj.getClass().getMethod(methodName); + return method.invoke(obj); + } + + private void setMethodValue(Object obj, String methodName, Object value) throws Exception { + Method method = obj.getClass().getMethod(methodName, value.getClass()); + method.invoke(obj, value); + } + /** * Builds a white-space separated list of concept ids belonging to a concept set * diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index 5b0a72cb..198f87a8 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -185,7 +185,6 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) * @param field field of the reference range * @param errorCode error code * @param defaultMessage default message - * * @since 1.17.0 */ private static void setReferenceRangeErrors(BindException errors, long index, String field, String errorCode, diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java index 9408ef0f..5ea93e16 100644 --- a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -35,15 +35,14 @@ public class ConceptFormMapper { * * @param webReferenceRange webReferenceRange * @param cn ConceptNumeric - * @param referenceRangeClass reference range class * @return reference range */ public Object mapToConceptReferenceRange( ConceptReferenceRange webReferenceRange, - ConceptNumeric cn, - Class referenceRangeClass) { + ConceptNumeric cn) { try { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); Object referenceRange = referenceRangeClass.getDeclaredConstructor().newInstance(); referenceRangeClass.getMethod("setCriteria", String.class).invoke(referenceRange, webReferenceRange.getCriteria()); @@ -59,7 +58,8 @@ public Object mapToConceptReferenceRange( return referenceRange; - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException exception) { + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException | + ClassNotFoundException exception) { logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); } return null; @@ -77,7 +77,6 @@ public List mapToWebReferenceRanges(ConceptNumeric cn) { try { Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges"); Object referenceRanges = getReferenceRangesMethod.invoke(cn); - System.out.println("In mapper:- getReferenceRangesMethod name = " + getReferenceRangesMethod); for (Object referenceRange : (Set) referenceRanges) { ConceptReferenceRange webReferenceRange = new ConceptReferenceRange(); diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index eb1b8c91..b3223947 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -339,10 +339,10 @@ class='evenRow'> - - + +
diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index d8966064..76d6b038 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -342,10 +342,10 @@ class='evenRow'> - - + +
diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 35dcd7f7..f5aa61be 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -158,7 +158,6 @@ #addAnswerError{ margin-bottom: 0.5em; border: 1px dashed black; background: #FAA; line-height: 2em; text-align: center; display: none; } #headerRow th { text-align: center; } #footer { clear:both; } - #newReferenceRange { display: none; } diff --git a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java index 7b82d53f..3cf5685a 100644 --- a/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/ConceptFormControllerTest.java @@ -1319,184 +1319,121 @@ public void shouldSetAttributesToVoidIfTheValueIsNotSet() throws Exception { Assert.assertTrue(((ConceptAttribute) (concept.getAttributes().toArray()[0])).getVoided()); Assert.assertFalse(errors.hasErrors()); } - - /** To be uncommented when the openmrs-core version in this module is ultimately changed to 2.7.0 or above - - -// /** -// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, -// * BindException) -// / - @Test - public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() throws Exception { - ConceptService cs = Context.getConceptService(); - - ConceptNumeric conceptNumeric = cs.getConceptNumeric(4090); - assertNotNull(conceptNumeric); - int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); - - ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - mockRequest.setMethod("POST"); - mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); - mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); - mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); - - ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); - assertNotNull(mav); - assertTrue(mav.getModel().isEmpty()); - assertEquals(initialConceptMappingCount + 1, getReferenceRangesByConceptId(cs, conceptNumeric.getConceptId())); - } - -// /** -// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, -// * BindException) -// / - @Test - public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() throws Exception { - ConceptService cs = Context.getConceptService(); - final String conceptName = "new concept"; - // make sure the concept doesn't already exist - Concept newConcept = cs.getConceptByName(conceptName); - assertNull(newConcept); - - ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); - - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - mockRequest.setMethod("POST"); - mockRequest.setParameter("action", ""); - mockRequest.setParameter("namesByLocale[en_GB].name", conceptName); - mockRequest.setParameter("descriptionsByLocale[en_GB].description", "some description"); - mockRequest.setParameter("concept.datatype", "1"); - mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); - mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); - mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); - - ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); - assertNotNull(mav); - assertTrue(mav.getModel().isEmpty()); - - Concept createdConcept = cs.getConceptByName(conceptName); - assertNotNull(createdConcept); - assertTrue(createdConcept instanceof ConceptNumeric); - - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges", referenceRangeClass); - Set listOfReferenceRanges = (Set) getReferenceRangesMethod.invoke(createdConcept, null); - Assert.assertEquals(1, listOfReferenceRanges.size()); - } -// /** -// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, -// * BindException) -// / - @Test - public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyData() throws Exception { - ConceptService cs = Context.getConceptService(); - - int conceptId = 4090; - ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); - assertNotNull(conceptNumeric); - int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); - - ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - mockRequest.setMethod("POST"); - mockRequest.setParameter("action", ""); - mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); - mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); - mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); - mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); - - ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); - assertNotNull(mav); - assertTrue(mav.getModel().isEmpty()); - - assertEquals(initialConceptMappingCount, getReferenceRangesByConceptId(cs, conceptId).size()); - } - -// /** -// * @see ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, -// * BindException) -// / - @Test - public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() throws Exception { - ConceptService cs = Context.getConceptService(); - int conceptId = 4090; - - // make sure the concept already exists and has some concept mappings - ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); - assertNotNull(conceptNumeric); - int initialConceptMappingCount = getReferenceRangesFromConceptNumeric(conceptNumeric).size(); - assertTrue(initialConceptMappingCount > 0); - - ConceptFormController conceptFormController = (ConceptFormController) applicationContext.getBean("conceptForm"); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - mockRequest.setMethod("POST"); - mockRequest.setParameter("action", ""); - mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); - mockRequest.setParameter("referenceRanges[0].id", "0"); - - ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); - assertNotNull(mav); - assertTrue(mav.getModel().isEmpty()); - - assertEquals(initialConceptMappingCount - 1, getReferenceRangesByConceptId(cs, conceptId).size()); - } - -// /** -// * @see ConceptFormValidator#validateConceptReferenceRange(Concept, BindException) -// / - @Test - public void validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound() { - ConceptNumeric conceptNumeric = new ConceptNumeric(); - conceptNumeric.setHiAbsolute(100.0); - conceptNumeric.setLowAbsolute(80.0); - ConceptReferenceRange referenceRange = new ConceptReferenceRange(); - referenceRange.setHiAbsolute(1100.0); - referenceRange.setLowAbsolute(1.0); - updateConceptReferenceRange(referenceRange, conceptNumeric); - BindException errors = new BindException(conceptNumeric, "conceptNumeric"); - new ConceptFormValidator().validateConceptReferenceRange(conceptNumeric, errors); - Assert.assertEquals(1, errors.getErrorCount()); - assertTrue(errors.hasFieldErrors("referenceRanges[0].hiAbsolute")); - assertTrue(errors.hasFieldErrors("referenceRanges[0].lowAbsolute")); - } - - private void updateConceptReferenceRange( - ConceptReferenceRange webReferenceRange, - ConceptNumeric cn) { - - try { - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - Object referenceRange = new ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, referenceRangeClass); - Method addReferenceRangeMethod = ConceptNumeric.class.getMethod("addReferenceRange", referenceRangeClass); - addReferenceRangeMethod.invoke(cn, referenceRange); - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { - logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); - } - } - - private static Set getReferenceRangesByConceptId(ConceptService cs, int conceptId) throws NoSuchMethodException, - IllegalAccessException, InvocationTargetException { - Method getConceptReferenceRangesByConceptIdMethod = ConceptService.class.getMethod( - "getConceptReferenceRangesByConceptId", Integer.class); - return (Set) getConceptReferenceRangesByConceptIdMethod.invoke(cs, conceptId); - } - - private static Set getReferenceRangesFromConceptNumeric(ConceptNumeric conceptNumeric) throws NoSuchMethodException, - IllegalAccessException, InvocationTargetException { - Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges"); - return (Set) getReferenceRangesMethod.invoke(conceptNumeric); - } - - */ + /** + * To be uncommented when the openmrs-core version in this module is ultimately changed to 2.7.0 + * or above // /** // * @see ConceptFormController#onSubmit(HttpServletRequest, + * HttpServletResponse, Object, // * BindException) // / + * + * @Test public void onSubmit_shouldAddANewReferenceRangeToAnExistingConceptNumeric() throws + * Exception { ConceptService cs = Context.getConceptService(); ConceptNumeric + * conceptNumeric = cs.getConceptNumeric(4090); assertNotNull(conceptNumeric); int + * initialConceptMappingCount = + * getReferenceRangesFromConceptNumeric(conceptNumeric).size(); ConceptFormController + * conceptFormController = (ConceptFormController) + * applicationContext.getBean("conceptForm"); MockHttpServletRequest mockRequest = new + * MockHttpServletRequest(); MockHttpServletResponse response = new + * MockHttpServletResponse(); mockRequest.setMethod("POST"); + * mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + * mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + * mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + * ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + * assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); + * assertEquals(initialConceptMappingCount + 1, getReferenceRangesByConceptId(cs, + * conceptNumeric.getConceptId())); } // /** // * @see + * ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, // * + * BindException) // / + * @Test public void onSubmit_shouldAddANewReferenceRangeWhenCreatingAConceptNumeric() throws + * Exception { ConceptService cs = Context.getConceptService(); final String conceptName = + * "new concept"; // make sure the concept doesn't already exist Concept newConcept = + * cs.getConceptByName(conceptName); assertNull(newConcept); ConceptFormController + * conceptFormController = (ConceptFormController) + * applicationContext.getBean("conceptForm"); MockHttpServletRequest mockRequest = new + * MockHttpServletRequest(); MockHttpServletResponse response = new + * MockHttpServletResponse(); mockRequest.setMethod("POST"); + * mockRequest.setParameter("action", ""); + * mockRequest.setParameter("namesByLocale[en_GB].name", conceptName); + * mockRequest.setParameter("descriptionsByLocale[en_GB].description", + * "some description"); mockRequest.setParameter("concept.datatype", "1"); + * mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + * mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + * mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + * ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + * assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); Concept createdConcept = + * cs.getConceptByName(conceptName); assertNotNull(createdConcept); + * assertTrue(createdConcept instanceof ConceptNumeric); Class referenceRangeClass = + * Class.forName("org.openmrs.ConceptReferenceRange"); Method getReferenceRangesMethod = + * ConceptNumeric.class.getMethod("getReferenceRanges", referenceRangeClass); Set + * listOfReferenceRanges = (Set) getReferenceRangesMethod.invoke(createdConcept, null); + * Assert.assertEquals(1, listOfReferenceRanges.size()); } // /** // * @see + * ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, // * + * BindException) // / + * @Test public void onSubmit_shouldIgnoreNewConceptReferenceRowIfTheUserDidNotEnterAnyData() + * throws Exception { ConceptService cs = Context.getConceptService(); int conceptId = + * 4090; ConceptNumeric conceptNumeric = cs.getConceptNumeric(conceptId); + * assertNotNull(conceptNumeric); int initialConceptMappingCount = + * getReferenceRangesFromConceptNumeric(conceptNumeric).size(); ConceptFormController + * conceptFormController = (ConceptFormController) + * applicationContext.getBean("conceptForm"); MockHttpServletRequest mockRequest = new + * MockHttpServletRequest(); MockHttpServletResponse response = new + * MockHttpServletResponse(); mockRequest.setMethod("POST"); + * mockRequest.setParameter("action", ""); mockRequest.setParameter("conceptId", + * conceptNumeric.getConceptId().toString()); + * mockRequest.setParameter("referenceRanges[0].hiAbasolute", "120"); + * mockRequest.setParameter("referenceRanges[0].lowAbsolute", "100"); + * mockRequest.setParameter("referenceRanges[0].criteria", "$fn.getAge() > 3"); + * ModelAndView mav = conceptFormController.handleRequest(mockRequest, response); + * assertNotNull(mav); assertTrue(mav.getModel().isEmpty()); + * assertEquals(initialConceptMappingCount, getReferenceRangesByConceptId(cs, + * conceptId).size()); } // /** // * @see + * ConceptFormController#onSubmit(HttpServletRequest, HttpServletResponse, Object, // * + * BindException) // / + * @Test public void onSubmit_shouldRemoveAReferenceRangeFromAnExistingConceptNumeric() throws + * Exception { ConceptService cs = Context.getConceptService(); int conceptId = 4090; // + * make sure the concept already exists and has some concept mappings ConceptNumeric + * conceptNumeric = cs.getConceptNumeric(conceptId); assertNotNull(conceptNumeric); int + * initialConceptMappingCount = + * getReferenceRangesFromConceptNumeric(conceptNumeric).size(); + * assertTrue(initialConceptMappingCount > 0); ConceptFormController conceptFormController + * = (ConceptFormController) applicationContext.getBean("conceptForm"); + * MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + * MockHttpServletResponse response = new MockHttpServletResponse(); + * mockRequest.setMethod("POST"); mockRequest.setParameter("action", ""); + * mockRequest.setParameter("conceptId", conceptNumeric.getConceptId().toString()); + * mockRequest.setParameter("referenceRanges[0].id", "0"); ModelAndView mav = + * conceptFormController.handleRequest(mockRequest, response); assertNotNull(mav); + * assertTrue(mav.getModel().isEmpty()); assertEquals(initialConceptMappingCount - 1, + * getReferenceRangesByConceptId(cs, conceptId).size()); } // /** // * @see + * ConceptFormValidator#validateConceptReferenceRange(Concept, BindException) // / + * @Test public void + * validateReferenceRangeAbsolutes_shouldAddErrorIfAbsolutesAreOutsideConceptAbsoluteBound + * () { ConceptNumeric conceptNumeric = new ConceptNumeric(); + * conceptNumeric.setHiAbsolute(100.0); conceptNumeric.setLowAbsolute(80.0); + * ConceptReferenceRange referenceRange = new ConceptReferenceRange(); + * referenceRange.setHiAbsolute(1100.0); referenceRange.setLowAbsolute(1.0); + * updateConceptReferenceRange(referenceRange, conceptNumeric); BindException errors = new + * BindException(conceptNumeric, "conceptNumeric"); new + * ConceptFormValidator().validateConceptReferenceRange(conceptNumeric, errors); + * Assert.assertEquals(1, errors.getErrorCount()); + * assertTrue(errors.hasFieldErrors("referenceRanges[0].hiAbsolute")); + * assertTrue(errors.hasFieldErrors("referenceRanges[0].lowAbsolute")); } private void + * updateConceptReferenceRange( ConceptReferenceRange webReferenceRange, ConceptNumeric + * cn) { try { Class referenceRangeClass = + * Class.forName("org.openmrs.ConceptReferenceRange"); Object referenceRange = new + * ConceptFormMapper().mapToConceptReferenceRange(webReferenceRange, cn, + * referenceRangeClass); Method addReferenceRangeMethod = + * ConceptNumeric.class.getMethod("addReferenceRange", referenceRangeClass); + * addReferenceRangeMethod.invoke(cn, referenceRange); } catch (InvocationTargetException + * | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { + * logger.error("Failed to add reference range: Exception: " + exception.getMessage(), + * exception); } } private static Set getReferenceRangesByConceptId(ConceptService cs, int + * conceptId) throws NoSuchMethodException, IllegalAccessException, + * InvocationTargetException { Method getConceptReferenceRangesByConceptIdMethod = + * ConceptService.class.getMethod( "getConceptReferenceRangesByConceptId", Integer.class); + * return (Set) getConceptReferenceRangesByConceptIdMethod.invoke(cs, conceptId); } + * private static Set getReferenceRangesFromConceptNumeric(ConceptNumeric conceptNumeric) + * throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + * Method getReferenceRangesMethod = ConceptNumeric.class.getMethod("getReferenceRanges"); + * return (Set) getReferenceRangesMethod.invoke(conceptNumeric); } + */ } diff --git a/pom.xml b/pom.xml index e861ba92..e5878b34 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 2.0.0 + 2.7.0-SNAPSHOT UTF-8 1.8 From 04dfa3f357b78203804282540269fc0ae9047b3f Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sat, 14 Sep 2024 23:28:44 +0300 Subject: [PATCH 18/30] Reverting the core version --- .../web/servlet/mvc/AbstractWizardFormController.java | 4 +--- pom.xml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java b/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java index 2d95fafc..200ff95a 100644 --- a/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java +++ b/omod/src/main/java/org/springframework/web/servlet/mvc/AbstractWizardFormController.java @@ -654,9 +654,7 @@ protected int getTargetPage(HttpServletRequest request, Object command, Errors e * @see #PARAM_TARGET */ protected int getTargetPage(HttpServletRequest request, int currentPage) { - return 0; - // TODO REVERT THIS AFTER TESTING IS DONE - // return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage); + return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage); } /** diff --git a/pom.xml b/pom.xml index e5878b34..e861ba92 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 2.7.0-SNAPSHOT + 2.0.0 UTF-8 1.8 From 270311a5d785a80713a64af062c27593b07ba76d Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Tue, 17 Sep 2024 17:47:57 +0300 Subject: [PATCH 19/30] Sorting reference ranges --- .../org/openmrs/web/controller/ConceptFormController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 502e5740..efad281f 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -24,6 +25,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -528,7 +530,11 @@ public ConceptFormBackingObject(Concept concept) { this.units = cn.getUnits(); this.referenceRanges = ListUtils.lazyList( - new ArrayList<>(new ConceptFormMapper().mapToWebReferenceRanges(cn)), + new ArrayList<>(new ConceptFormMapper().mapToWebReferenceRanges(cn) + .stream() + .sorted(Comparator.comparing(ConceptReferenceRange::getId)) + .collect(Collectors.toList()) + ), FactoryUtils.instantiateFactory(ConceptReferenceRange.class)); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; From d3dd8339e3eb54f08a0d1a1db92077855cc06723 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 18 Sep 2024 00:04:16 +0300 Subject: [PATCH 20/30] Fixing null pointer --- .../org/openmrs/web/controller/ConceptFormController.java | 6 +----- .../org/openmrs/web/controller/ConceptFormValidator.java | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index efad281f..3f6b7f45 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -530,11 +530,7 @@ public ConceptFormBackingObject(Concept concept) { this.units = cn.getUnits(); this.referenceRanges = ListUtils.lazyList( - new ArrayList<>(new ConceptFormMapper().mapToWebReferenceRanges(cn) - .stream() - .sorted(Comparator.comparing(ConceptReferenceRange::getId)) - .collect(Collectors.toList()) - ), + new ArrayList<>(new ConceptFormMapper().mapToWebReferenceRanges(cn)), FactoryUtils.instantiateFactory(ConceptReferenceRange.class)); } else if (concept instanceof ConceptComplex) { ConceptComplex complex = (ConceptComplex) concept; diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index 198f87a8..b2be28ee 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -139,7 +139,9 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) int index = 0; for (ConceptReferenceRange referenceRange : referenceRanges) { - if (referenceRange.getId() == null) { + if (referenceRange.getId() == null + && conceptNumeric.getHiAbsolute() != null + && conceptNumeric.getLowAbsolute() != null) { if (referenceRange.getHiAbsolute() == null) { setReferenceRangeErrors(errors, index, "hiAbsolute", "Concept.referenceRanges.error.high.absolute.value.required", From 6cd4978c3389bbb8fea6e1f4c52e33d296945bf5 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Wed, 18 Sep 2024 09:53:15 +0300 Subject: [PATCH 21/30] Code refactor --- .../org/openmrs/web/controller/ConceptFormValidator.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index b2be28ee..3280755d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -139,9 +139,8 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) int index = 0; for (ConceptReferenceRange referenceRange : referenceRanges) { - if (referenceRange.getId() == null - && conceptNumeric.getHiAbsolute() != null - && conceptNumeric.getLowAbsolute() != null) { + if (referenceRange.getId() == null && conceptNumeric.getHiAbsolute() != null + && conceptNumeric.getLowAbsolute() != null) { if (referenceRange.getHiAbsolute() == null) { setReferenceRangeErrors(errors, index, "hiAbsolute", "Concept.referenceRanges.error.high.absolute.value.required", From 36634bb5ed3406db5467c312be2fe1a9ad6fe638 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sun, 22 Sep 2024 11:25:41 +0300 Subject: [PATCH 22/30] Ability to edit concept reference ranges --- .../web/controller/ConceptFormController.java | 145 ++++++++++++------ .../main/webapp/dictionary/conceptForm.jsp | 14 +- 2 files changed, 107 insertions(+), 52 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 3f6b7f45..088f8fad 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -25,7 +25,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -468,7 +467,7 @@ public class ConceptFormBackingObject { public Collection activeAttributes; - public List referenceRanges; + public List referenceRanges; /** * Default constructor must take in a Concept object to create itself @@ -696,8 +695,7 @@ public Concept getConceptFromFormData() { } /** - * This method sets reference ranges to concept numeric. If an existing reference range was - * removed, then we remove it from concept numeric. + * This method sets reference ranges to concept numeric. * * @param cn ConceptNumeric * @since 1.17.0 @@ -713,63 +711,68 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { if (referenceRange.getId() != null) { if (referenceRange.getId() <= 0) { - try { - Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange( - referenceRange, cn); - setMethodValue(cn, "removeReferenceRange", platformReferenceRange); - } - catch (Exception exception) { - logger.error("Failed to remove reference range: Exception: " + exception.getMessage(), exception); - } + removeReferenceRange(cn, referenceRange); } else { updateReferenceRange(cn, referenceRange); } } else { - referenceRange.setConceptNumeric(cn); - try { - Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange(referenceRange, - cn); - setMethodValue(cn, "addReferenceRange", platformReferenceRange); - } - catch (Exception exception) { - logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); - } + addReferenceRange(cn, referenceRange); } } } + /** + * This method removes a reference range from conceptNumeric + * + * @param cn conceptNumeric + * @param referenceRange referenceRange + * @since 1.17.0 + */ + private void removeReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenceRange) { + try { + Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange(referenceRange, cn); + setMethodValue(cn, "removeReferenceRange", platformReferenceRange); + } + catch (Exception exception) { + logger.error("Failed to remove reference range: Exception: " + exception.getMessage(), exception); + } + } + + /** + * This method adds a new reference range to conceptNumeric + * + * @param cn conceptNumeric + * @param referenceRange referenceRange + * @since 1.17.0 + */ + private void addReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenceRange) { + referenceRange.setConceptNumeric(cn); + try { + Object platformReferenceRange = new ConceptFormMapper().mapToConceptReferenceRange(referenceRange, cn); + setMethodValue(cn, "addReferenceRange", platformReferenceRange); + } + catch (Exception exception) { + logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + } + } + /** * This method updates concept reference range if a field value has changed. * + * @param cn ConceptNumeric + * @param referenceRange ConceptReferenceRange * @since 1.17.0 */ public void updateReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenceRange) { try { - Method getReferenceRangesMethod = cn.getClass().getMethod("getReferenceRanges"); - Set referenceRanges = (Set) getReferenceRangesMethod.invoke(cn); - - for (Object rr : referenceRanges) { - Method getIdMethod = rr.getClass().getMethod("getId"); - Object idValue = getIdMethod.invoke(rr); - - if (Objects.equals(idValue, referenceRange.getId())) { + Set existingReferenceRanges = getExistingReferenceRanges(cn); - if (!referenceRange.getCriteria().equals(getMethodValue(rr, "getCriteria")) || - !Objects.equals(referenceRange.getHiAbsolute(), getMethodValue(rr, "getHiAbsolute")) || - !Objects.equals(referenceRange.getHiCritical(), getMethodValue(rr, "getHiCritical")) || - !Objects.equals(referenceRange.getHiNormal(), getMethodValue(rr, "getHiNormal")) || - !Objects.equals(referenceRange.getLowAbsolute(), getMethodValue(rr, "getLowAbsolute")) || - !Objects.equals(referenceRange.getLowCritical(), getMethodValue(rr, "getLowCritical")) || - !Objects.equals(referenceRange.getLowNormal(), getMethodValue(rr, "getLowNormal"))) { + for (Object existingRange : existingReferenceRanges) { + Method getIdMethod = existingRange.getClass().getMethod("getId"); + Object idValue = getIdMethod.invoke(existingRange); - setMethodValue(rr, "setHiAbsolute", referenceRange.getHiAbsolute()); - setMethodValue(rr, "setHiCritical", referenceRange.getHiCritical()); - setMethodValue(rr, "setHiNormal", referenceRange.getHiNormal()); - setMethodValue(rr, "setLowAbsolute", referenceRange.getLowAbsolute()); - setMethodValue(rr, "setLowCritical", referenceRange.getLowCritical()); - setMethodValue(rr, "setLowNormal", referenceRange.getLowNormal()); - setMethodValue(rr, "setCriteria", referenceRange.getCriteria()); - } + if (Objects.equals(idValue, referenceRange.getId()) && hasReferenceRangeChanged(existingRange, referenceRange)) { + updateReferenceRangeFields(existingRange, referenceRange); break; } } @@ -781,6 +784,58 @@ public void updateReferenceRange(ConceptNumeric cn, ConceptReferenceRange refere } } + /** + * This method gets the existing reference ranges + * + * @param cn ConceptNumeric + * @return a set of reference ranges + * @since 1.17.0 + */ + private Set getExistingReferenceRanges(ConceptNumeric cn) { + try { + Method getReferenceRangesMethod = cn.getClass().getMethod("getReferenceRanges"); + return (Set) getReferenceRangesMethod.invoke(cn); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + logger.error("Failed to retrieve reference ranges: Exception: " + e.getMessage(), e); + return Collections.emptySet(); + } + } + + private boolean hasReferenceRangeChanged(Object existingRange, ConceptReferenceRange referenceRange) + throws Exception { + return !Objects.equals(referenceRange.getCriteria(), getMethodValue(existingRange, "getCriteria")) + || !Objects.equals(referenceRange.getHiAbsolute(), getMethodValue(existingRange, "getHiAbsolute")) + || !Objects.equals(referenceRange.getHiCritical(), getMethodValue(existingRange, "getHiCritical")) + || !Objects.equals(referenceRange.getHiNormal(), getMethodValue(existingRange, "getHiNormal")) + || !Objects.equals(referenceRange.getLowAbsolute(), getMethodValue(existingRange, "getLowAbsolute")) + || !Objects.equals(referenceRange.getLowCritical(), getMethodValue(existingRange, "getLowCritical")) + || !Objects.equals(referenceRange.getLowNormal(), getMethodValue(existingRange, "getLowNormal")); + } + + /** + * This method updates reference range fields + * + * @param existingRange existing reference range + * @param referenceRange the updated reference range + * @throws Exception exception + * @since 1.17.0 + */ + private void updateReferenceRangeFields(Object existingRange, ConceptReferenceRange referenceRange) throws Exception { + updateField(existingRange, "setHiAbsolute", referenceRange.getHiAbsolute()); + updateField(existingRange, "setHiCritical", referenceRange.getHiCritical()); + updateField(existingRange, "setHiNormal", referenceRange.getHiNormal()); + updateField(existingRange, "setLowAbsolute", referenceRange.getLowAbsolute()); + updateField(existingRange, "setLowCritical", referenceRange.getLowCritical()); + updateField(existingRange, "setLowNormal", referenceRange.getLowNormal()); + updateField(existingRange, "setCriteria", referenceRange.getCriteria()); + } + + private void updateField(Object obj, String methodName, Object value) throws Exception { + if (value != null) { + setMethodValue(obj, methodName, value); + } + } + private Object getMethodValue(Object obj, String methodName) throws Exception { Method method = obj.getClass().getMethod(methodName); return method.invoke(obj); diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index f5aa61be..2a2f5a87 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -839,13 +839,13 @@ - - - - - - - + + + + + + + From 2194cfb2abbdc762dc56cfb9457840643093aaa0 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sun, 22 Sep 2024 21:25:49 +0300 Subject: [PATCH 23/30] Updating reference range validations --- .../web/controller/ConceptFormValidator.java | 33 +++++++++++++++---- omod/src/main/resources/messages.properties | 4 +-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java index 3280755d..ad97791d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormValidator.java @@ -139,17 +139,16 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) int index = 0; for (ConceptReferenceRange referenceRange : referenceRanges) { - if (referenceRange.getId() == null && conceptNumeric.getHiAbsolute() != null - && conceptNumeric.getLowAbsolute() != null) { + if (conceptNumeric.getHiAbsolute() != null && conceptNumeric.getLowAbsolute() != null) { if (referenceRange.getHiAbsolute() == null) { setReferenceRangeErrors(errors, index, "hiAbsolute", "Concept.referenceRanges.error.high.absolute.value.required", "Concept.referenceRanges.error.absolute.value.required"); } else { if (referenceRange.getHiAbsolute() > conceptNumeric.getHiAbsolute()) { - setReferenceRangeErrors(errors, index, "hiAbsolute", + setReferenceRangeErrorsWithValue(errors, index, "hiAbsolute", "Concept.referenceRanges.error.highAbsolute.value.outOfRange", - "Concept.referenceRanges.error.absolute.value.invalid"); + referenceRange.getHiAbsolute(), conceptNumeric.getHiAbsolute()); } else if (referenceRange.getHiAbsolute() < conceptNumeric.getLowAbsolute()) { setReferenceRangeErrors(errors, index, "hiAbsolute", "Concept.referenceRanges.error.absolute.value.invalid", @@ -162,9 +161,9 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) "Concept.referenceRanges.error.absolute.value.required"); } else { if (referenceRange.getLowAbsolute() < conceptNumeric.getLowAbsolute()) { - setReferenceRangeErrors(errors, index, "lowAbsolute", + setReferenceRangeErrorsWithValue(errors, index, "lowAbsolute", "Concept.referenceRanges.error.lowAbsolute.value.outOfRange", - "Concept.referenceRanges.error.absolute.value.invalid"); + referenceRange.getLowAbsolute(), conceptNumeric.getLowAbsolute()); } else if (referenceRange.getLowAbsolute() > conceptNumeric.getHiAbsolute()) { setReferenceRangeErrors(errors, index, "lowAbsolute", "Concept.referenceRanges.error.absolute.value.invalid", @@ -188,10 +187,30 @@ public void validateConceptReferenceRange(Concept concept, BindException errors) * @param defaultMessage default message * @since 1.17.0 */ - private static void setReferenceRangeErrors(BindException errors, long index, String field, String errorCode, + private void setReferenceRangeErrors(BindException errors, long index, String field, String errorCode, String defaultMessage) { errors.pushNestedPath("referenceRanges[" + index + "]"); errors.rejectValue(field, errorCode, defaultMessage); errors.popNestedPath(); } + + /** + * Set Reference Range Errors with values + * + * @param errors BindException + * @param index index of referenceRange row + * @param field field of the reference range + * @param errorCode error code + * @param value current high or low absolute value + * @param thresholdValue high or low absolute value of conceptNumeric + * @since 1.17.0 + */ + private void setReferenceRangeErrorsWithValue(BindException errors, long index, String field, String errorCode, + Double value, Double thresholdValue) { + errors.pushNestedPath("referenceRanges[" + index + "]"); + errors.rejectValue(field, + Context.getMessageSourceService().getMessage(errorCode, new Object[] { value, thresholdValue }, null), + "Concept.referenceRanges.error.absolute.value.invalid"); + errors.popNestedPath(); + } } diff --git a/omod/src/main/resources/messages.properties b/omod/src/main/resources/messages.properties index 81d94957..4f17ef82 100644 --- a/omod/src/main/resources/messages.properties +++ b/omod/src/main/resources/messages.properties @@ -5,6 +5,6 @@ Concept.referenceRanges.add=Add a Reference Range Concept.referenceRanges.error.low.absolute.value.required=Low Absolute cannot be empty Concept.referenceRanges.error.high.absolute.value.required=High Absolute cannot be empty Concept.referenceRanges.error.absolute.value.required=Absolute value cannot be empty -Concept.referenceRanges.error.highAbsolute.value.outOfRange=High Absolute in reference range cannot be higher than high absolute value of the concept -Concept.referenceRanges.error.lowAbsolute.value.outOfRange=Low Absolute in reference range cannot be lower than low absolute value of the concept +Concept.referenceRanges.error.highAbsolute.value.outOfRange=High Absolute {0} cannot exceed concept''s High Absolute {1} +Concept.referenceRanges.error.lowAbsolute.value.outOfRange=Low Absolute {0} cannot be below concept''s Low Absolute {1} Concept.referenceRanges.error.absolute.value.invalid=Invalid absolute value of reference range \ No newline at end of file From 71fea3e77f24406977b6cac2b33a7ddb138e237b Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Sun, 22 Sep 2024 22:26:55 +0300 Subject: [PATCH 24/30] Reconciliation of admin and dictionary views --- .../web/controller/ConceptFormController.java | 1 - .../concept/ConceptReferenceRange.java | 33 ++++++++++++------- .../controller/mappper/ConceptFormMapper.java | 4 +-- .../webapp/admin/dictionary/conceptForm.jsp | 14 ++++---- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index 088f8fad..d87898a4 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -850,7 +850,6 @@ private void setMethodValue(Object obj, String methodName, Object value) throws * Builds a white-space separated list of concept ids belonging to a concept set * * @return white-space separated list - * @since 1.17.0 */ public String getSetElements() { StringBuilder result = new StringBuilder(); diff --git a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java index 08388bdd..bdde6d0d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java +++ b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java @@ -12,8 +12,11 @@ import org.openmrs.ConceptNumeric; /** - * This class is a view object of reference range. A concept reference range is typically a range of - * a {@link ConceptNumeric} for certain factor(s) e.g. age, gender e.t.c. + * This class represents a reference range for a {@link ConceptNumeric}. It is used to store + * and manage reference range values, to be able to allow backward compatibility in openmrs core versions. + * + * A concept reference range defines the acceptable numeric values/ranges for specific factors + * such as age, gender, e.t.c. * * @since 1.17.0 */ @@ -43,13 +46,17 @@ public ConceptReferenceRange() { } /** - * @return Returns the conceptRangeId. + * Gets id of conceptReferenceRange + * + * @return Returns the ConceptReferenceRangeId. */ public Integer getConceptReferenceRangeId() { return conceptReferenceRangeId; } /** + * Sets conceptReferenceRangeId + * * @param conceptReferenceRangeId The conceptReferenceRangeId to set. */ public void setConceptReferenceRangeId(Integer conceptReferenceRangeId) { @@ -57,16 +64,16 @@ public void setConceptReferenceRangeId(Integer conceptReferenceRangeId) { } /** - * Returns the criteria of the conceptReferenceRange + * Gets the criteria of conceptReferenceRange * - * @return criteria the criteria + * @return criteria */ public String getCriteria() { return this.criteria; } /** - * Sets the criteria of the conceptReferenceRange + * Sets the criteria of conceptReferenceRange * * @param criteria the criteria to set */ @@ -75,6 +82,8 @@ public void setCriteria(String criteria) { } /** + * Gets conceptNumeric of conceptReferenceRange + * * @return Returns the ConceptNumeric. */ public ConceptNumeric getConceptNumeric() { @@ -82,6 +91,8 @@ public ConceptNumeric getConceptNumeric() { } /** + * Sets conceptNumeric + * * @param conceptNumeric concept to set. */ public void setConceptNumeric(ConceptNumeric conceptNumeric) { @@ -117,7 +128,7 @@ public void setUuid(String uuid) { } /** - * Returns high absolute value of the referenceRange + * Gets high absolute value of the referenceRange * * @return hiAbsolute the high absolute value */ @@ -135,7 +146,7 @@ public void setHiAbsolute(Double hiAbsolute) { } /** - * Returns high critical value of the referenceRange + * Gets high critical value of the referenceRange * * @return the high critical value */ @@ -171,7 +182,7 @@ public void setHiNormal(Double hiNormal) { } /** - * Returns low absolute value of the referenceRange + * Gets low absolute value of the referenceRange * * @return the low absolute value */ @@ -189,7 +200,7 @@ public void setLowAbsolute(Double lowAbsolute) { } /** - * Returns low critical value of the referenceRange + * Gets low critical value of the referenceRange * * @return the low critical value */ @@ -207,7 +218,7 @@ public void setLowCritical(Double lowCritical) { } /** - * Returns low normal value of the referenceRange + * Gets low normal value of the referenceRange * * @return the low normal value */ diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java index 5ea93e16..deefea81 100644 --- a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -31,7 +31,7 @@ public class ConceptFormMapper { protected final Log logger = LogFactory.getLog(getClass()); /** - * Maps reference range in openMRS core to web's reference range + * Maps web's reference range to reference range in openMRS core * * @param webReferenceRange webReferenceRange * @param cn ConceptNumeric @@ -66,7 +66,7 @@ public Object mapToConceptReferenceRange( } /** - * Maps web's reference range to reference range in openMRS core + * Maps reference ranges in openMRS core to web's reference ranges * * @param cn ConceptNumeric * @return list of reference range diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index f0e3889e..0909d878 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -839,13 +839,13 @@ - - - - - - - + + + + + + + From 29ffdacc6997e84768456dd1cbf70ccd8d953360 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Fri, 27 Sep 2024 16:50:29 +0300 Subject: [PATCH 25/30] Fixing an error when 2 rows are added and the first one removed before saving --- .../web/controller/ConceptFormController.java | 4 +++- .../concept/ConceptReferenceRange.java | 17 ++++++++--------- .../controller/mappper/ConceptFormMapper.java | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index d87898a4..fcb25389 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -716,7 +716,9 @@ private void setConceptReferenceRanges(ConceptNumeric cn) { updateReferenceRange(cn, referenceRange); } } else { - addReferenceRange(cn, referenceRange); + if (referenceRange.getHiAbsolute() != null && referenceRange.getLowAbsolute() != null) { + addReferenceRange(cn, referenceRange); + } } } } diff --git a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java index bdde6d0d..b0b95713 100644 --- a/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java +++ b/omod/src/main/java/org/openmrs/web/controller/concept/ConceptReferenceRange.java @@ -12,11 +12,10 @@ import org.openmrs.ConceptNumeric; /** - * This class represents a reference range for a {@link ConceptNumeric}. It is used to store - * and manage reference range values, to be able to allow backward compatibility in openmrs core versions. - * - * A concept reference range defines the acceptable numeric values/ranges for specific factors - * such as age, gender, e.t.c. + * This class represents a reference range for a {@link ConceptNumeric}. It is used to store and + * manage reference range values, to be able to allow backward compatibility in openmrs core + * versions. A concept reference range defines the acceptable numeric values/ranges for specific + * factors such as age, gender, e.t.c. * * @since 1.17.0 */ @@ -47,7 +46,7 @@ public ConceptReferenceRange() { /** * Gets id of conceptReferenceRange - * + * * @return Returns the ConceptReferenceRangeId. */ public Integer getConceptReferenceRangeId() { @@ -56,7 +55,7 @@ public Integer getConceptReferenceRangeId() { /** * Sets conceptReferenceRangeId - * + * * @param conceptReferenceRangeId The conceptReferenceRangeId to set. */ public void setConceptReferenceRangeId(Integer conceptReferenceRangeId) { @@ -83,7 +82,7 @@ public void setCriteria(String criteria) { /** * Gets conceptNumeric of conceptReferenceRange - * + * * @return Returns the ConceptNumeric. */ public ConceptNumeric getConceptNumeric() { @@ -92,7 +91,7 @@ public ConceptNumeric getConceptNumeric() { /** * Sets conceptNumeric - * + * * @param conceptNumeric concept to set. */ public void setConceptNumeric(ConceptNumeric conceptNumeric) { diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java index deefea81..325b726d 100644 --- a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -31,7 +31,7 @@ public class ConceptFormMapper { protected final Log logger = LogFactory.getLog(getClass()); /** - * Maps web's reference range to reference range in openMRS core + * Maps web's reference range to reference range in openMRS core * * @param webReferenceRange webReferenceRange * @param cn ConceptNumeric @@ -66,7 +66,7 @@ public Object mapToConceptReferenceRange( } /** - * Maps reference ranges in openMRS core to web's reference ranges + * Maps reference ranges in openMRS core to web's reference ranges * * @param cn ConceptNumeric * @return list of reference range From a66e598da080c9f4a8e4f5f02c91bda9bc38b58a Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Tue, 8 Oct 2024 16:01:59 +0300 Subject: [PATCH 26/30] Conditional display of concept reference ranges based on openMRS-core version --- .../web/controller/ConceptFormController.java | 14 ++- .../controller/mappper/ConceptFormMapper.java | 4 +- .../main/webapp/admin/dictionary/concept.jsp | 2 +- .../webapp/admin/dictionary/conceptForm.jsp | 116 +++++++++--------- omod/src/main/webapp/dictionary/concept.jsp | 2 +- .../main/webapp/dictionary/conceptForm.jsp | 116 +++++++++--------- 6 files changed, 131 insertions(+), 123 deletions(-) diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index fcb25389..e7e5bc99 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -414,6 +414,9 @@ protected Map referenceData(HttpServletRequest request) throws E map.put("locale", Context.getLocale()); // should be same string format as conceptNamesByLocale map keys map.put("attributeTypes", cs.getAllConceptAttributeTypes()); + + String openmrsVersion = OpenmrsConstants.OPENMRS_VERSION; + map.put("openmrsVersion", openmrsVersion); return map; } @@ -736,7 +739,8 @@ private void removeReferenceRange(ConceptNumeric cn, ConceptReferenceRange refer setMethodValue(cn, "removeReferenceRange", platformReferenceRange); } catch (Exception exception) { - logger.error("Failed to remove reference range: Exception: " + exception.getMessage(), exception); + logger.warn("Failed to remove concept reference range. " + + "Note that openMRS-core version 2.7.* or higher is required for this functionality to work."); } } @@ -754,7 +758,7 @@ private void addReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenc setMethodValue(cn, "addReferenceRange", platformReferenceRange); } catch (Exception exception) { - logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. } } @@ -780,9 +784,9 @@ public void updateReferenceRange(ConceptNumeric cn, ConceptReferenceRange refere } } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { - logger.error("Failed to update reference range: Exception: " + exception.getMessage(), exception); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. } catch (Exception exception) { - logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. } } @@ -798,7 +802,7 @@ private Set getExistingReferenceRanges(ConceptNumeric cn) { Method getReferenceRangesMethod = cn.getClass().getMethod("getReferenceRanges"); return (Set) getReferenceRangesMethod.invoke(cn); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - logger.error("Failed to retrieve reference ranges: Exception: " + e.getMessage(), e); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. return Collections.emptySet(); } } diff --git a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java index 325b726d..60dcbb78 100644 --- a/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java +++ b/omod/src/main/java/org/openmrs/web/controller/mappper/ConceptFormMapper.java @@ -60,7 +60,7 @@ public Object mapToConceptReferenceRange( } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException | ClassNotFoundException exception) { - logger.error("Failed to add reference range: Exception: " + exception.getMessage(), exception); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. } return null; } @@ -95,7 +95,7 @@ public List mapToWebReferenceRanges(ConceptNumeric cn) { webReferenceRanges.add(webReferenceRange); } } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { - logger.error("Failed to map to web reference range: Exception: " + e.getMessage(), e); + // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. } return webReferenceRanges; diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index b3223947..acb33e29 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,7 +319,7 @@ - + "> diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index 0909d878..80080aa3 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -820,63 +820,65 @@ - - - "/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- - - ${status.errorMessage} - -
- -
- - + + + + "/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ + + ${status.errorMessage} + +
+ +
+ + +
"/> diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index 76d6b038..fa511f70 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,7 +322,7 @@ - + "> diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 2a2f5a87..37d0ea40 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -820,63 +820,65 @@ - - - "/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- - - ${status.errorMessage} - -
- -
- - + + + + "/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ + + ${status.errorMessage} + +
+ +
+ + +
From dd54bf1d6eefccad080a459b7537b7a75ea121c4 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Fri, 11 Oct 2024 19:15:47 +0300 Subject: [PATCH 27/30] Refactoring --- .../openmrs/module/legacyui/GeneralUtils.java | 46 +++++++++++++++++++ .../web/controller/ConceptFormController.java | 16 +++---- .../main/webapp/admin/dictionary/concept.jsp | 2 +- .../webapp/admin/dictionary/conceptForm.jsp | 2 +- omod/src/main/webapp/dictionary/concept.jsp | 2 +- .../main/webapp/dictionary/conceptForm.jsp | 2 +- 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java index e54e934f..0d561297 100644 --- a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java +++ b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java @@ -11,6 +11,7 @@ import org.openmrs.Concept; import org.openmrs.api.context.Context; +import org.openmrs.util.OpenmrsConstants; public class GeneralUtils { @@ -68,4 +69,49 @@ public static Concept getConcept(String id) { return cpt; } + + /** + * Checks if current version of openmrs is greater or equal to 2.7.0 + * + * @return true if current version is greater or equal to 2.7.0 and false otherwise + * @since 1.17.0 + */ + public static boolean isTwoPointSevenAndAbove() { + String openmrsVersion = OpenmrsConstants.OPENMRS_VERSION_SHORT; + + if (openmrsVersion.isEmpty()) { + return false; + } + + return isVersionAbove(openmrsVersion.substring(0, 5), "2.7.0"); + } + + /** + * This method simply compares a version with the target version and returns true if the version + * is subject is greater or equal to the target version + * + * @param version current version + * @param targetVersion target version + * @return true if version is greater or equal to the target version + * @since 1.17.0 + */ + private static boolean isVersionAbove(String version, String targetVersion) { + String[] currentVersionParts = version.split("\\."); + String[] targetVersionParts = targetVersion.split("\\."); + + int length = Math.max(currentVersionParts.length, targetVersionParts.length); + + for (int i = 0; i < length; i++) { + int currentPart = i < currentVersionParts.length ? Integer.parseInt(currentVersionParts[i]) : 0; + int targetPart = i < targetVersionParts.length ? Integer.parseInt(targetVersionParts[i]) : 0; + + if (currentPart < targetPart) { + return false; + } else if (currentPart > targetPart) { + return true; + } + } + + return true; + } } diff --git a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java index e7e5bc99..93abe55e 100644 --- a/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/ConceptFormController.java @@ -58,6 +58,7 @@ import org.openmrs.api.ConceptsLockedException; import org.openmrs.api.DuplicateConceptNameException; import org.openmrs.api.context.Context; +import org.openmrs.module.legacyui.GeneralUtils; import org.openmrs.module.web.extension.ConceptUsageExtension; import org.openmrs.module.web.extension.provider.Link; import org.openmrs.propertyeditor.ConceptAnswersEditor; @@ -415,8 +416,8 @@ protected Map referenceData(HttpServletRequest request) throws E map.put("attributeTypes", cs.getAllConceptAttributeTypes()); - String openmrsVersion = OpenmrsConstants.OPENMRS_VERSION; - map.put("openmrsVersion", openmrsVersion); + map.put("canUseConceptReferenceRanges", GeneralUtils.isTwoPointSevenAndAbove()); + return map; } @@ -739,8 +740,7 @@ private void removeReferenceRange(ConceptNumeric cn, ConceptReferenceRange refer setMethodValue(cn, "removeReferenceRange", platformReferenceRange); } catch (Exception exception) { - logger.warn("Failed to remove concept reference range. " - + "Note that openMRS-core version 2.7.* or higher is required for this functionality to work."); + // Note that openMRS-core version 2.7.0 or higher is required for this functionality to work. } } @@ -758,7 +758,7 @@ private void addReferenceRange(ConceptNumeric cn, ConceptReferenceRange referenc setMethodValue(cn, "addReferenceRange", platformReferenceRange); } catch (Exception exception) { - // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. + // Note that openMRS-core version 2.7.0 or higher is required for this functionality to work. } } @@ -784,9 +784,9 @@ public void updateReferenceRange(ConceptNumeric cn, ConceptReferenceRange refere } } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException exception) { - // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. + // Note that openMRS-core version 2.7.0 or higher is required for this functionality to work. } catch (Exception exception) { - // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. + // Note that openMRS-core version 2.7.0 or higher is required for this functionality to work. } } @@ -802,7 +802,7 @@ private Set getExistingReferenceRanges(ConceptNumeric cn) { Method getReferenceRangesMethod = cn.getClass().getMethod("getReferenceRanges"); return (Set) getReferenceRangesMethod.invoke(cn); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - // Note that openMRS-core version 2.7.* or higher is required for this functionality to work. + // Note that openMRS-core version 2.7.0 or higher is required for this functionality to work. return Collections.emptySet(); } } diff --git a/omod/src/main/webapp/admin/dictionary/concept.jsp b/omod/src/main/webapp/admin/dictionary/concept.jsp index acb33e29..eaaab601 100644 --- a/omod/src/main/webapp/admin/dictionary/concept.jsp +++ b/omod/src/main/webapp/admin/dictionary/concept.jsp @@ -319,7 +319,7 @@ - + "> diff --git a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp index 80080aa3..b672506f 100644 --- a/omod/src/main/webapp/admin/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/admin/dictionary/conceptForm.jsp @@ -820,7 +820,7 @@ - + "/> diff --git a/omod/src/main/webapp/dictionary/concept.jsp b/omod/src/main/webapp/dictionary/concept.jsp index fa511f70..3ba17778 100644 --- a/omod/src/main/webapp/dictionary/concept.jsp +++ b/omod/src/main/webapp/dictionary/concept.jsp @@ -322,7 +322,7 @@ - + "> diff --git a/omod/src/main/webapp/dictionary/conceptForm.jsp b/omod/src/main/webapp/dictionary/conceptForm.jsp index 37d0ea40..7ad6644e 100644 --- a/omod/src/main/webapp/dictionary/conceptForm.jsp +++ b/omod/src/main/webapp/dictionary/conceptForm.jsp @@ -820,7 +820,7 @@ - + "/> From 988d9175beac7cceed00d126258a66b29a1acd0d Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 17 Oct 2024 19:06:20 +0300 Subject: [PATCH 28/30] code refactor --- .../openmrs/module/legacyui/GeneralUtils.java | 43 ++++--------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java index 0d561297..5bd19d32 100644 --- a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java +++ b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java @@ -11,7 +11,6 @@ import org.openmrs.Concept; import org.openmrs.api.context.Context; -import org.openmrs.util.OpenmrsConstants; public class GeneralUtils { @@ -72,46 +71,20 @@ public static Concept getConcept(String id) { /** * Checks if current version of openmrs is greater or equal to 2.7.0 + * The aim is to try loading ConceptReferenceRange class and one of its method, which is in version 2.7.0. + * If the ConceptReferenceRange class is loaded, then the current version is greater or equal than 2.7.0 * * @return true if current version is greater or equal to 2.7.0 and false otherwise * @since 1.17.0 */ public static boolean isTwoPointSevenAndAbove() { - String openmrsVersion = OpenmrsConstants.OPENMRS_VERSION_SHORT; - - if (openmrsVersion.isEmpty()) { + try { + Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); + referenceRangeClass.getMethod("getCriteria", String.class); + + return true; + } catch (NoSuchMethodException | ClassNotFoundException exception) { return false; } - - return isVersionAbove(openmrsVersion.substring(0, 5), "2.7.0"); - } - - /** - * This method simply compares a version with the target version and returns true if the version - * is subject is greater or equal to the target version - * - * @param version current version - * @param targetVersion target version - * @return true if version is greater or equal to the target version - * @since 1.17.0 - */ - private static boolean isVersionAbove(String version, String targetVersion) { - String[] currentVersionParts = version.split("\\."); - String[] targetVersionParts = targetVersion.split("\\."); - - int length = Math.max(currentVersionParts.length, targetVersionParts.length); - - for (int i = 0; i < length; i++) { - int currentPart = i < currentVersionParts.length ? Integer.parseInt(currentVersionParts[i]) : 0; - int targetPart = i < targetVersionParts.length ? Integer.parseInt(targetVersionParts[i]) : 0; - - if (currentPart < targetPart) { - return false; - } else if (currentPart > targetPart) { - return true; - } - } - - return true; } } From a98b7353fe62d7a5f95a95fd3203685b9cf2c428 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Thu, 17 Oct 2024 19:07:32 +0300 Subject: [PATCH 29/30] code refactor --- .../java/org/openmrs/module/legacyui/GeneralUtils.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java index 5bd19d32..accfb2de 100644 --- a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java +++ b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java @@ -11,6 +11,7 @@ import org.openmrs.Concept; import org.openmrs.api.context.Context; +import org.openmrs.util.OpenmrsConstants; public class GeneralUtils { @@ -70,9 +71,10 @@ public static Concept getConcept(String id) { } /** - * Checks if current version of openmrs is greater or equal to 2.7.0 - * The aim is to try loading ConceptReferenceRange class and one of its method, which is in version 2.7.0. - * If the ConceptReferenceRange class is loaded, then the current version is greater or equal than 2.7.0 + * Checks if current version of openmrs is greater or equal to 2.7.0 The aim is to try loading + * ConceptReferenceRange class and one of its method, which is in version 2.7.0. If the + * ConceptReferenceRange class is loaded, then the current version is greater than or equal to + * 2.7.0 * * @return true if current version is greater or equal to 2.7.0 and false otherwise * @since 1.17.0 @@ -80,7 +82,7 @@ public static Concept getConcept(String id) { public static boolean isTwoPointSevenAndAbove() { try { Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - referenceRangeClass.getMethod("getCriteria", String.class); + referenceRangeClass.getMethod("getCriteria"); return true; } catch (NoSuchMethodException | ClassNotFoundException exception) { From 2be1fed8cf83145ca24749b2c0f671ea3de572b6 Mon Sep 17 00:00:00 2001 From: Isaiah Muli Date: Fri, 18 Oct 2024 10:31:44 +0300 Subject: [PATCH 30/30] removed unnecessary method --- .../org/openmrs/module/legacyui/GeneralUtils.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java index accfb2de..90bd0448 100644 --- a/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java +++ b/api/src/main/java/org/openmrs/module/legacyui/GeneralUtils.java @@ -72,20 +72,19 @@ public static Concept getConcept(String id) { /** * Checks if current version of openmrs is greater or equal to 2.7.0 The aim is to try loading - * ConceptReferenceRange class and one of its method, which is in version 2.7.0. If the - * ConceptReferenceRange class is loaded, then the current version is greater than or equal to - * 2.7.0 + * ConceptReferenceRange class, which is in version 2.7.0. If the ConceptReferenceRange class is + * loaded, then the current version is greater than or equal to 2.7.0 * * @return true if current version is greater or equal to 2.7.0 and false otherwise * @since 1.17.0 */ public static boolean isTwoPointSevenAndAbove() { try { - Class referenceRangeClass = Class.forName("org.openmrs.ConceptReferenceRange"); - referenceRangeClass.getMethod("getCriteria"); - + Class.forName("org.openmrs.ConceptReferenceRange"); + return true; - } catch (NoSuchMethodException | ClassNotFoundException exception) { + } + catch (ClassNotFoundException exception) { return false; } }