diff --git a/api-2.2/pom.xml b/api-2.2/pom.xml new file mode 100644 index 000000000..2b16bd644 --- /dev/null +++ b/api-2.2/pom.xml @@ -0,0 +1,82 @@ + + 4.0.0 + + + org.openmrs.module + htmlformentry + 3.10.0-SNAPSHOT + + + htmlformentry-api-2.2 + jar + htmlformentry Module api 2.2 + 2.2 api project for htmlformentry + + + 2.2.0 + + + + + ${project.parent.groupId} + ${project.parent.artifactId}-api + ${project.parent.version} + + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + provided + + + + org.openmrs.test + openmrs-test + pom + ${openMRSVersion} + + + + org.openmrs.web + openmrs-web + + + + javax.servlet + javax.servlet-api + 3.0.1 + test + + + + + + + + src/main/resources + true + + + + + + src/test/resources + + **/*.properties + **/*.xml + + true + + + src/test/resources + + **/*.properties + **/*.xml + + false + + + + + diff --git a/api-2.2/src/main/java/org/openmrs/module/htmlformentry/ConditionElement.java b/api-2.2/src/main/java/org/openmrs/module/htmlformentry/ConditionElement.java new file mode 100644 index 000000000..ff73097c3 --- /dev/null +++ b/api-2.2/src/main/java/org/openmrs/module/htmlformentry/ConditionElement.java @@ -0,0 +1,272 @@ +package org.openmrs.module.htmlformentry; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.openmrs.CodedOrFreeText; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Condition; +import org.openmrs.ConditionClinicalStatus; +import org.openmrs.api.ConditionService; +import org.openmrs.api.context.Context; +import org.openmrs.messagesource.MessageSourceService; +import org.openmrs.module.htmlformentry.FormEntryContext.Mode; +import org.openmrs.module.htmlformentry.action.FormSubmissionControllerAction; +import org.openmrs.module.htmlformentry.element.HtmlGeneratorElement; +import org.openmrs.module.htmlformentry.widget.DateWidget; +import org.openmrs.module.htmlformentry.widget.ErrorWidget; +import org.openmrs.module.htmlformentry.widget.Option; +import org.openmrs.module.htmlformentry.widget.RadioButtonsWidget; +import org.openmrs.module.htmlformentry.widget.Widget; +import org.openmrs.module.htmlformentry.widget.ConceptSearchAutocompleteWidget; + +public class ConditionElement implements HtmlGeneratorElement, FormSubmissionControllerAction { + + private MessageSourceService mss; + private ConditionService conditionService; + private boolean required; + private final String CONDITION_LIST_CONCEPT_CLASS_NAME = "Diagnosis"; + + // widgets + private Widget conditionSearchWidget; + private DateWidget onSetDateWidget; + private DateWidget endDateWidget; + private RadioButtonsWidget conditionStatusesWidget; + private ErrorWidget endDateErrorWidget; + private ErrorWidget conditionSearchErrorWidget; + private ErrorWidget conditionStatusesErrorWidget; + + @Override + public void handleSubmission(FormEntrySession session, HttpServletRequest submission) { + FormEntryContext context = session.getContext(); + if (context.getMode() != Mode.VIEW) { + Condition condition = new Condition(); + CodedOrFreeText conditionConcept = new CodedOrFreeText(); + try { + int conceptId = Integer.parseInt((String) conditionSearchWidget.getValue(session.getContext(), submission)); + conditionConcept.setCoded(new Concept(conceptId)); + + } catch(NumberFormatException e) { + String nonCodedConcept = submission.getParameter(context.getFieldName(conditionSearchWidget)); + conditionConcept.setNonCoded(nonCodedConcept); + } + condition.setCondition(conditionConcept); + condition.setClinicalStatus(getStatus(context, submission)); + condition.setOnsetDate(onSetDateWidget.getValue(context, submission)); + if (ConditionClinicalStatus.INACTIVE == getStatus(context, submission)) { + condition.setEndDate(endDateWidget.getValue(context, submission)); + } + condition.setPatient(session.getPatient()); + conditionService = Context.getConditionService(); + conditionService.saveCondition(condition); + } + } + + @Override + public Collection validateSubmission(FormEntryContext context, HttpServletRequest submission) { + List ret = new ArrayList(); + Date givenOnsetDate = onSetDateWidget.getValue(context, submission); + Date givenEndDate = endDateWidget.getValue(context, submission); + String condition = StringUtils.isNotBlank((String) conditionSearchWidget.getValue(context, submission)) ? + (String) conditionSearchWidget.getValue(context, submission) : submission.getParameter(context.getFieldName(conditionSearchWidget)); + ConditionClinicalStatus status = getStatus(context, submission); + + if (context.getMode() != Mode.VIEW) { + if (StringUtils.isBlank(condition) && required) { + ret.add(new FormSubmissionError(context.getFieldName(conditionSearchWidget), + Context.getMessageSourceService().getMessage("htmlformentry.conditionui.condition.required"))); + } + if (givenOnsetDate != null && givenEndDate != null) { + if (givenOnsetDate.after(givenEndDate)) { + ret.add(new FormSubmissionError(context.getFieldName(endDateWidget), + Context.getMessageSourceService().getMessage("htmlformentry.conditionui.endDate.before.onsetDate.error"))); + } + } + if (status == null && required) { + ret.add(new FormSubmissionError(context.getFieldName(conditionStatusesWidget), + Context.getMessageSourceService().getMessage("htmlformentry.conditionui.status.required"))); + } + } + return ret; + } + + @Override + public String generateHtml(FormEntryContext context) { + StringBuilder ret = new StringBuilder(); + ret.append("
"); + ret.append(htmlForConditionSearchWidget(context)); + ret.append(htmlForConditionStatusesWidgets(context)); + ret.append(htmlForConditionDatesWidget(context)); + ret.append("
"); + return ret.toString(); + } + + private String htmlForConditionSearchWidget(FormEntryContext context) { + Set initialConcepts = new HashSet(); + if (mss == null) { + mss = Context.getMessageSourceService(); + } + ConceptClass conceptClass = Context.getConceptService().getConceptClassByName(CONDITION_LIST_CONCEPT_CLASS_NAME); + initialConcepts.addAll(Context.getConceptService().getConceptsByClass(conceptClass)); + conditionSearchWidget = new ConceptSearchAutocompleteWidget(new ArrayList(initialConcepts), Arrays.asList(conceptClass)); + String conditionNameTextInputId = context.registerWidget(conditionSearchWidget); + conditionSearchErrorWidget = new ErrorWidget(); + context.registerErrorWidget(conditionSearchWidget, conditionSearchErrorWidget); + + StringBuilder ret = new StringBuilder(); + ret.append(conditionSearchWidget.generateHtml(context)); + if (context.getMode() != Mode.VIEW) { + ret.append(conditionSearchErrorWidget.generateHtml(context)); + } + ret.append("\n\n"); + return ret.toString(); + } + + private String htmlForConditionStatusesWidgets(FormEntryContext context) { + if (mss == null) { + mss = Context.getMessageSourceService(); + } + Option active = new Option(mss.getMessage("coreapps.conditionui.active.label"), "active", false); + Option inactive = new Option(mss.getMessage("coreapps.conditionui.inactive.label"), "inactive", false); + Option historyOf = new Option(mss.getMessage("htmlformentry.conditionui.historyOf.label"), "history-of", false); + conditionStatusesWidget = new RadioButtonsWidget(); + conditionStatusesErrorWidget = new ErrorWidget(); + conditionStatusesWidget.addOption(active); + conditionStatusesWidget.addOption(inactive); + conditionStatusesWidget.addOption(historyOf); + String radioGroupName = context.registerWidget(conditionStatusesWidget); + context.registerErrorWidget(conditionStatusesWidget, conditionStatusesErrorWidget); + + StringBuilder sb = new StringBuilder(); + sb.append("
"); + sb.append(conditionStatusesErrorWidget.generateHtml(context)); + sb.append(conditionStatusesWidget.generateHtml(context)); + sb.append(""); + sb.append(""); + sb.append("
"); + return sb.toString(); + } + + private String htmlForConditionDatesWidget(FormEntryContext context) { + onSetDateWidget = new DateWidget(); + if (mss == null) { + mss = Context.getMessageSourceService(); + } + String onsetDateTextInputId = context.registerWidget(onSetDateWidget) + "-display"; + endDateWidget = new DateWidget(); + endDateErrorWidget = new ErrorWidget(); + String endDateTextInputId = context.registerWidget(endDateWidget) + "-display"; + context.registerErrorWidget(endDateWidget, endDateErrorWidget); + + StringBuilder ret = new StringBuilder(); + ret.append("
    "); + ret.append("
  • "); + ret.append(onSetDateWidget.generateHtml(context)); + ret.append("
  • "); + ret.append(""); + ret.append(endDateWidget.generateHtml(context)); + ret.append(""); + ret.append("
  • "); + if (context.getMode() != Mode.VIEW) { + ret.append(endDateErrorWidget.generateHtml(context)); + } + ret.append("

"); + ret.append(""); + ret.append(""); + return ret.toString(); + } + + private ConditionClinicalStatus getStatus(FormEntryContext context, HttpServletRequest request) { + if (conditionStatusesWidget == null) { + return null; + } + Object status = conditionStatusesWidget.getValue(context, request); + if (status != null) { + if (((String)status).equals("active")) { + return ConditionClinicalStatus.ACTIVE; + } + if (((String)status).equals("inactive")) { + return ConditionClinicalStatus.INACTIVE; + } + if (((String)status).equals("history-of")) { + return ConditionClinicalStatus.HISTORY_OF; + } + } + return null; + } + + public void setConditionSearchWidget(Widget conditionSearchWidget) { + this.conditionSearchWidget = conditionSearchWidget; + } + + public void setOnSetDateWidget(DateWidget onSetDateWidget) { + this.onSetDateWidget = onSetDateWidget; + } + + public void setEndDateWidget(DateWidget endDateWidget) { + this.endDateWidget = endDateWidget; + } + + public void setConditionStatusesWidget(RadioButtonsWidget conditionStatusesWidget) { + this.conditionStatusesWidget = conditionStatusesWidget; + } + + public void setRequired(boolean required) { + this.required = required; + } + +} diff --git a/api-2.2/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport2_2.java b/api-2.2/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport2_2.java new file mode 100644 index 000000000..cc702ab92 --- /dev/null +++ b/api-2.2/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport2_2.java @@ -0,0 +1,24 @@ +package org.openmrs.module.htmlformentry.handler; + +import java.util.Map; + +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.htmlformentry.ConditionElement; +import org.openmrs.module.htmlformentry.FormEntrySession; +import org.openmrs.module.htmlformentry.FormSubmissionController; + +@OpenmrsProfile(openmrsPlatformVersion = "2.2.*") +public class ConditionTagHandlerSupport2_2 implements ConditionTagHandlerSupport { + + @Override + public String getSubstitution(FormEntrySession session, FormSubmissionController controller, Map attributes) { + ConditionElement element = new ConditionElement(); + String required = attributes.get("required"); + if (required != null) { + element.setRequired(required.equalsIgnoreCase("true")); + } + session.getSubmissionController().addAction(element); + return element.generateHtml(session.getContext()); + } + +} diff --git a/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandler.java b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandler.java new file mode 100644 index 000000000..b8a8b9731 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandler.java @@ -0,0 +1,21 @@ +package org.openmrs.module.htmlformentry.handler; + +import java.util.Map; + +import org.openmrs.module.htmlformentry.BadFormDesignException; +import org.openmrs.module.htmlformentry.FormEntrySession; +import org.openmrs.module.htmlformentry.FormSubmissionController; +import org.springframework.beans.factory.annotation.Autowired; + +public class ConditionTagHandler extends SubstitutionTagHandler { + + @Autowired + private ConditionTagHandlerSupport handler; + + @Override + protected String getSubstitution(FormEntrySession session, FormSubmissionController controllerActions, + Map parameters) throws BadFormDesignException { + return handler.getSubstitution(session, controllerActions, parameters); + } + +} diff --git a/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport.java b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport.java new file mode 100644 index 000000000..8ebfbea99 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport.java @@ -0,0 +1,13 @@ +package org.openmrs.module.htmlformentry.handler; + +import java.util.Map; + +import org.openmrs.module.htmlformentry.FormEntrySession; +import org.openmrs.module.htmlformentry.FormSubmissionController; + +public interface ConditionTagHandlerSupport { + + String getSubstitution(FormEntrySession session, + FormSubmissionController controllerActions, + Map parameters); +} diff --git a/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport1_10.java b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport1_10.java new file mode 100644 index 000000000..fb2388b06 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/htmlformentry/handler/ConditionTagHandlerSupport1_10.java @@ -0,0 +1,18 @@ +package org.openmrs.module.htmlformentry.handler; + +import java.util.Map; + +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.htmlformentry.FormEntrySession; +import org.openmrs.module.htmlformentry.FormSubmissionController; + +@OpenmrsProfile(openmrsPlatformVersion = "[1.10 - 2.1.*]") +public class ConditionTagHandlerSupport1_10 implements ConditionTagHandlerSupport { + + @Override + public String getSubstitution(FormEntrySession session, FormSubmissionController controllerActions, + Map parameters) { + throw new RuntimeException("The Condition tag should be used on 2.2.0 platform version and above."); + } + +} diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties index 89db6585b..69885cb40 100644 --- a/api/src/main/resources/messages.properties +++ b/api/src/main/resources/messages.properties @@ -94,6 +94,11 @@ htmlformentry.chooseAnEncounterRole=Choose an Encounter Role htmlformentry.unknownProviderName=Unknown htmlformentry.providerPlaceHolder=Type identifier or name +# Condition UI +htmlformentry.conditionui.historyOf.label=History Of +htmlformentry.conditionui.condition.required=Condition required +htmlformentry.conditionui.status.required=Condition status required +htmlformentry.conditionui.endDate.before.onsetDate.error=End date cannot be before onset date diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml index 6af721fb1..4a24b6521 100644 --- a/api/src/main/resources/moduleApplicationContext.xml +++ b/api/src/main/resources/moduleApplicationContext.xml @@ -133,6 +133,11 @@ obsreference + + condition + + + diff --git a/omod/pom.xml b/omod/pom.xml index 3b395d768..24955fe36 100644 --- a/omod/pom.xml +++ b/omod/pom.xml @@ -33,6 +33,11 @@ htmlformentry-api-2.0 ${project.parent.version} + + org.openmrs.module + htmlformentry-api-2.2 + ${project.parent.version} + org.openmrs.api openmrs-api diff --git a/pom.xml b/pom.xml index 839f192da..4e17998d2 100644 --- a/pom.xml +++ b/pom.xml @@ -203,6 +203,7 @@ api-1.9 api-1.10 api-2.0 + api-2.2 api-tests omod