Package org.openmrs.module.htmlformentry.element

Source Code of org.openmrs.module.htmlformentry.element.DrugOrderSubmissionElement

package org.openmrs.module.htmlformentry.element;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

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.ConceptAnswer;
import org.openmrs.Drug;
import org.openmrs.DrugOrder;
import org.openmrs.api.ConceptService;
import org.openmrs.api.context.Context;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.module.htmlformentry.FormEntryContext;
import org.openmrs.module.htmlformentry.FormEntryContext.Mode;
import org.openmrs.module.htmlformentry.FormEntrySession;
import org.openmrs.module.htmlformentry.FormSubmissionError;
import org.openmrs.module.htmlformentry.HtmlFormEntryUtil;
import org.openmrs.module.htmlformentry.action.FormSubmissionControllerAction;
import org.openmrs.module.htmlformentry.schema.DrugOrderAnswer;
import org.openmrs.module.htmlformentry.schema.DrugOrderField;
import org.openmrs.module.htmlformentry.schema.ObsFieldAnswer;
import org.openmrs.module.htmlformentry.widget.CheckboxWidget;
import org.openmrs.module.htmlformentry.widget.DateWidget;
import org.openmrs.module.htmlformentry.widget.DropdownWidget;
import org.openmrs.module.htmlformentry.widget.ErrorWidget;
import org.openmrs.module.htmlformentry.widget.NumberFieldWidget;
import org.openmrs.module.htmlformentry.widget.Option;
import org.openmrs.module.htmlformentry.widget.TextFieldWidget;
import org.openmrs.module.htmlformentry.widget.Widget;
import org.openmrs.util.OpenmrsConstants;

/**
* Holds the widgets used to represent a specific drug order, and serves as both the HtmlGeneratorElement
* and the FormSubmissionControllerAction for the drug order.
*/
public class DrugOrderSubmissionElement implements HtmlGeneratorElement,
    FormSubmissionControllerAction, GettingExistingOrder {

  protected final Log log = LogFactory.getLog(DrugOrderSubmissionElement.class);

  public static final String FIELD_DRUG_NAMES = "drugNames";

  public static final String FIELD_DOSE = "dose";

  public static final String FIELD_VALIDATE_DOSE = "validateDose";

  public static final String FIELD_UNITS = "units";

  public static final String FIELD_DISCONTINUED = "discontinued";

  public static final String FIELD_FREQUENCY = "frequency";

  public static final String FIELD_QUANTITY = "quantity";

  public static final String FIELD_DATE_CREATED = "date_created";

  public static final String FIELD_INSTRUCTIONS_LABEL = "instructionsLabel";

  public static final String FIELD_DRUG_LABELS = "drugLabels";

  public static final String CONFIG_SHOW_DOSE_AND_FREQ = "hideDoseAndFrequency";

  public static final String FIELD_CHECKBOX = "checkbox";

  public static final String FIELD_DISCONTINUED_REASON="discontinuedReasonConceptId";

  public static final String FIELD_DISCONTINUED_REASON_ANSWERS="discontinueReasonAnswers";

  public static final String FIELD_DISCONTINUED_REASON_ANSWER_LABELS="discontinueReasonAnswerLabels";

  public static final String FIELD_SHOW_ORDER_DURATION = "showOrderDuration";

  public static final String CONFIG_DEFAULT_DOSE = "defaultDose";

  private boolean validateDose = false;

  protected Widget drugWidget;
  private ErrorWidget drugErrorWidget;
  protected Widget doseWidget;
  protected ErrorWidget doseErrorWidget;
  protected DateWidget startDateWidget;
  private ErrorWidget startDateErrorWidget;
  protected DateWidget discontinuedDateWidget;
  private ErrorWidget discontinuedDateErrorWidget;
  protected DropdownWidget frequencyWidget;
  protected ErrorWidget frequencyErrorWidget;
  private DropdownWidget frequencyWeekWidget;
  private ErrorWidget frequencyWeekErrorWidget;
  private TextFieldWidget instructionsWidget;
  private ErrorWidget instructionsErrorWidget;
  private String instructionsLabel;
  private List<String> drugLabels;
  protected Boolean hideDoseAndFrequency = false;
  private Boolean checkbox = false;
  protected DropdownWidget discontinuedReasonWidget;
    private ErrorWidget discontinuedReasonErrorWidget;
    private TextFieldWidget orderDurationWidget;
    private ErrorWidget orderDurationErrorWidget;
    private Double defaultDose;

  protected DrugOrder existingOrder;
  protected List<Drug> drugsUsedAsKey;


  public DrugOrderSubmissionElement(FormEntryContext context, Map<String, String> parameters) {
    ConceptService conceptService = Context.getConceptService();
    MessageSourceService mss = Context.getMessageSourceService();

    Boolean usingDurationField = false;
    String orderDurationStr = parameters.get(FIELD_SHOW_ORDER_DURATION);
    if (!StringUtils.isEmpty(orderDurationStr) && orderDurationStr.equals("true"))
        usingDurationField = true;
    String hideDoseAndFreqStr = parameters.get(CONFIG_SHOW_DOSE_AND_FREQ);
    if (!StringUtils.isEmpty(hideDoseAndFreqStr) && hideDoseAndFreqStr.equals("true"))
        hideDoseAndFrequency = true;

    String checkboxStr = parameters.get(FIELD_CHECKBOX);
        if (checkboxStr != null && checkboxStr.equals("true"))
            checkbox = true;

    // check URL
    String drugNames = parameters.get(FIELD_DRUG_NAMES);
    if (drugNames == null || drugNames.length() < 1)
      throw new IllegalArgumentException("You must provide a valid drug name, or a valid ID or a valid UUID in " + parameters);

    String fieldValidateDose = parameters.get(FIELD_VALIDATE_DOSE);
    if (fieldValidateDose != null && fieldValidateDose.length() > 1)
      validateDose = Boolean.parseBoolean(fieldValidateDose);

        if (parameters.get(FIELD_DRUG_LABELS) != null) {
            drugLabels = Arrays.asList(parameters.get(FIELD_DRUG_LABELS).split(","));
        }

    // fill drop down with drug names from database
    List<Option> options = new ArrayList<Option>();
    options.add(new Option("", "", false));

    // drugNames is comma separated list which can contain ID, UUID or drugname
    StringTokenizer tokenizer = new StringTokenizer(drugNames, ",");
    int drugListIndexPos = 0;
        String displayText = "";
        DrugOrderField dof = new DrugOrderField();
    while (tokenizer.hasMoreElements()) {
      String drugName = (String) tokenizer.nextElement();
      Drug drug = null;

      // see if this is a uuid
      if (HtmlFormEntryUtil.isValidUuidFormat(drugName.trim())) {
        drug = conceptService.getDrugByUuid(drugName.trim());
      }

      // if we didn't find by id, find by uuid or name
      if (drug == null){
        drug = conceptService.getDrugByNameOrId(drugName.trim());
      }

      if (drug != null) {
          displayText = drug.getName();
          if (drugLabels != null) {
              displayText = drugLabels.get(drugListIndexPos);
          }
        options.add(new Option(displayText, drug.getDrugId().toString(), false));
        if (drugsUsedAsKey == null) {
            drugsUsedAsKey = new ArrayList<Drug>();
        }
        drugsUsedAsKey.add(drug);
        DrugOrderAnswer doa = new DrugOrderAnswer(drug, displayText);
        dof.addDrugOrderAnswer(doa);
        drugListIndexPos ++;
      } else if (drugName.length() > 0 && drugName.charAt(0) == '/' && drugName.charAt(drugName.length()-1) == '/'){
          options.add(new Option("[ " + drugName.substring(1,drugName.length()-1) + " ]", "~", false));
      } else {
          throw new IllegalArgumentException("No Drug found for drug name/id/uuid " + drugName);
      }
    }

    if (drugsUsedAsKey == null)
      throw new IllegalArgumentException("You must provide a valid drug name, or a valid ID or a valid UUID in " + parameters);

        // there need to be the same number of drugs as drug labels
        if (drugLabels != null && drugsUsedAsKey.size() != drugLabels.size())
            throw new IllegalArgumentException("There are a different number of drugLabels (" + drugLabels.size() + ") than drugs (" + drugsUsedAsKey.size() + ").");


        // Register Drug Widget
        if (checkbox && drugsUsedAsKey.size() == 1){
            CheckboxWidget cb = new CheckboxWidget();
            cb.setLabel(displayText);
            cb.setValue(drugsUsedAsKey.get(0).getDrugId().toString());
            drugWidget = cb;
        } else {
            DropdownWidget dw = new DropdownWidget();
            dw.setOptions(options);
            drugWidget = dw;
        }
        context.registerWidget(drugWidget);
        drugErrorWidget = new ErrorWidget();
        context.registerErrorWidget(drugWidget, drugErrorWidget);

    //start date
    startDateWidget = new DateWidget();
        startDateErrorWidget = new ErrorWidget();
        context.registerWidget(startDateWidget);
        context.registerErrorWidget(startDateWidget, startDateErrorWidget);

        if (!hideDoseAndFrequency){
        // dose validation by drug is done in validateSubmission()
        doseWidget = new NumberFieldWidget(0d, 9999999d, true);
        //set default value (maybe temporarily)
        String defaultDoseStr = parameters.get(CONFIG_DEFAULT_DOSE);
        if (!StringUtils.isEmpty(defaultDoseStr)){
            try {
                defaultDose = Double.valueOf(defaultDoseStr);
                doseWidget.setInitialValue(defaultDose);
            } catch (Exception ex){
                    throw new RuntimeException("optional attribute 'defaultDose' must be numeric or empty.");
            }
        }

        doseErrorWidget = new ErrorWidget();
        context.registerWidget(doseWidget);
        context.registerErrorWidget(doseWidget, doseErrorWidget);

        createFrequencyWidget(context, mss);

        createFrequencyWeekWidget(context, mss);
        }

        if (!usingDurationField){
        discontinuedDateWidget = new DateWidget();
        discontinuedDateErrorWidget = new ErrorWidget();
        context.registerWidget(discontinuedDateWidget);
        context.registerErrorWidget(discontinuedDateWidget, discontinuedDateErrorWidget);
        }
    if (parameters.get(FIELD_DISCONTINUED_REASON) != null){
        String discReasonConceptStr = (String) parameters.get(FIELD_DISCONTINUED_REASON);
        Concept discontineReasonConcept = HtmlFormEntryUtil.getConcept(discReasonConceptStr);
        if (discontineReasonConcept == null)
            throw new IllegalArgumentException("discontinuedReasonConceptId is not set to a valid conceptId or concept UUID");
        dof.setDiscontinuedReasonQuestion(discontineReasonConcept);

        discontinuedReasonWidget = new DropdownWidget();
        discontinuedReasonErrorWidget = new ErrorWidget();

        List<Option> discOptions = new ArrayList<Option>();
        discOptions.add(new Option("", "", false));

        if (parameters.get(FIELD_DISCONTINUED_REASON_ANSWERS) != null){
            //setup a list of the reason concepts
            List<Concept> discReasons = new ArrayList<Concept>();
            String discAnswersString = (String) parameters.get(FIELD_DISCONTINUED_REASON_ANSWERS);
            String[] strDiscAnswers = discAnswersString.split(",");
            for (int i = 0; i < strDiscAnswers.length; i++){
                String thisAnswer = strDiscAnswers[i];
                Concept answer = HtmlFormEntryUtil.getConcept(thisAnswer, "discontinueReasonAnswers includes a value that is not a valid conceptId or concept UUID");
                  discReasons.add(answer);
            }

            if (parameters.get(FIELD_DISCONTINUED_REASON_ANSWER_LABELS) != null){
                // use the listed discontinueReasons, and use labels:
                String discLabelsString = parameters.get(FIELD_DISCONTINUED_REASON_ANSWER_LABELS);
                String[] strDiscAnswerLabels = discLabelsString.split(",");
                //a little validation:
                if (strDiscAnswerLabels.length != discReasons.size())
                    throw new RuntimeException("discontinueReasonAnswers and discontinueReasonAnswerLabels must contain the same number of members.");
                for (int i = 0; i < strDiscAnswerLabels.length; i ++ ){
                    discOptions.add(new Option( strDiscAnswerLabels[i], discReasons.get(i).getConceptId().toString(),false));
                    dof.addDiscontinuedReasonAnswer(new ObsFieldAnswer(strDiscAnswerLabels[i].trim(), discReasons.get(i)));
                }
            } else {
                // use the listed discontinueReasons, and use their ConceptNames.
                for (Concept c: discReasons){
                    discOptions.add(new Option( c.getBestName(Context.getLocale()).getName(), c.getConceptId().toString(),false));
                    dof.addDiscontinuedReasonAnswer(new ObsFieldAnswer(c.getBestName(Context.getLocale()).getName(), c));
                }
            }
        } else {
            //just use the conceptAnswers
            for (ConceptAnswer ca : discontineReasonConcept.getAnswers()){
                discOptions.add(new Option( ca.getAnswerConcept().getBestName(Context.getLocale()).getName(), ca.getAnswerConcept().getConceptId().toString(),false));
                dof.addDiscontinuedReasonAnswer(new ObsFieldAnswer(ca.getAnswerConcept().getBestName(Context.getLocale()).getName(), ca.getAnswerConcept()));
            }
        }
        if (discOptions.size() == 1)
            throw new IllegalArgumentException("discontinue reason Concept doesn't have any ConceptAnswers");

        discontinuedReasonWidget.setOptions(discOptions);
        context.registerWidget(discontinuedReasonWidget);
          context.registerErrorWidget(discontinuedReasonWidget, discontinuedReasonErrorWidget);
    }
   
    createAdditionalWidgets(context);
   
    if (context.getMode() != Mode.ENTER && context.getExistingOrders() != null) {
      // If VIEW, EDIT
      populateDrugOrderValuesFromDB(context, usingDurationField);
    }

        instructionsLabel = parameters.get(FIELD_INSTRUCTIONS_LABEL);
        if (instructionsLabel != null){
            instructionsWidget = new TextFieldWidget();
            if (existingOrder != null){
                instructionsWidget.setInitialValue(existingOrder.getInstructions());
            }
            instructionsErrorWidget = new ErrorWidget();
            context.registerWidget(instructionsWidget);
            context.registerErrorWidget(instructionsWidget, instructionsErrorWidget);
        }

        if (usingDurationField){
            orderDurationWidget = new TextFieldWidget(4);
            if (existingOrder != null && existingOrder.getAutoExpireDate() != null){
                //set duration from autoExpireDate in days
                Long autoDateMilis = existingOrder.getAutoExpireDate().getTime();
                Long startDateMilis = existingOrder.getStartDate().getTime();
                Long diffInMSec = autoDateMilis - startDateMilis;
                // Find date difference in days
                // (24 hours 60 minutes 60 seconds 1000 millisecond)
                Long diffOfDays = diffInMSec / (24 * 60 * 60 * 1000);
                orderDurationWidget.setInitialValue(String.valueOf(diffOfDays.intValue()));
            }
            orderDurationErrorWidget = new ErrorWidget();
            context.registerWidget(orderDurationWidget);
            context.registerErrorWidget(orderDurationWidget, orderDurationErrorWidget);
        }
        context.getSchema().addField(dof);
  }

  protected void createAdditionalWidgets(FormEntryContext context) {
     
    }

  /**
   * Be aware it's called by the constructor.
   * 
   * @param context
   * @param usingDurationField
   */
  protected void populateDrugOrderValuesFromDB(FormEntryContext context, Boolean usingDurationField) {
      for (Drug drug : drugsUsedAsKey) {
          if (context.getExistingOrders().containsKey(drug.getConcept())) {
              //this will return null if Order is not a DrugOrder even if matched by Concept
              DrugOrder drugOrder = (DrugOrder) context.removeExistingDrugOrder(drug);
              if (drugOrder != null){
              existingOrder = drugOrder;
              if (drugWidget instanceof DropdownWidget){
                  drugWidget.setInitialValue(drugOrder.getDrug().getDrugId());
              } else {
                  if (((CheckboxWidget) drugWidget).getValue().equals(drugOrder.getDrug().getDrugId().toString()))
                      ((CheckboxWidget) drugWidget).setInitialValue("CHECKED");
              }
              startDateWidget.setInitialValue(drugOrder.getStartDate());
              if (!hideDoseAndFrequency){
                  doseWidget.setInitialValue(drugOrder.getDose());
                  frequencyWidget.setInitialValue(parseFrequencyDays(drugOrder.getFrequency()));
                  frequencyWeekWidget.setInitialValue(parseFrequencyWeek(drugOrder.getFrequency()));
              }
              if (!usingDurationField){
                  discontinuedDateWidget.setInitialValue(drugOrder.getDiscontinuedDate());
                  if (discontinuedReasonWidget != null && drugOrder.getDiscontinuedReason() != null)
                      discontinuedReasonWidget.setInitialValue(drugOrder.getDiscontinuedReason().getConceptId());
              }
              break;
              }

          }
      }
    }

  /**
   * Be aware it's called by the constructor.
   *
   * @param context
   * @param mss
   */
  protected void createFrequencyWeekWidget(FormEntryContext context, MessageSourceService mss) {
      frequencyWeekWidget = new DropdownWidget();
      frequencyWeekErrorWidget = new ErrorWidget();
      // fill frequency drop down lists (ENTER, EDIT)
      List<Option> weekOptions = new ArrayList<Option>();
      if (context.getMode() != Mode.VIEW ) {
        for (int i = 7; i >= 1; i--) {
            weekOptions.add(new Option(i + " " + mss.getMessage("DrugOrder.frequency.days") + "/"  + mss.getMessage("DrugOrder.frequency.week") , String.valueOf(i), false));
          }
      }
      frequencyWeekWidget.setOptions(weekOptions);
      context.registerWidget(frequencyWeekWidget);
      context.registerErrorWidget(frequencyWeekWidget, frequencyWeekErrorWidget);
    }

  /**
   * Be aware it's called by the constructor.
   *
   * @param context
   * @param mss
   */
  protected void createFrequencyWidget(FormEntryContext context, MessageSourceService mss) {
      frequencyWidget = new DropdownWidget();
      frequencyErrorWidget = new ErrorWidget();
      // fill frequency drop down lists (ENTER, EDIT)
      List<Option> freqOptions = new ArrayList<Option>();
      if (context.getMode() != Mode.VIEW ) {
        for (int i = 1; i <= 10; i++) {
            freqOptions.add(new Option(i + "/" + mss.getMessage("DrugOrder.frequency.day"), String.valueOf(i), false));
        }
      }
      frequencyWidget.setOptions(freqOptions);
      context.registerWidget(frequencyWidget);
      context.registerErrorWidget(frequencyWidget, frequencyErrorWidget);
    }

  /**
   * Static helper method to parse frequency string
   *
   * @should return times per day which is part of frequency string
   * @param frequency (format "x/d y d/w")
   * @return x
   */
  private static String parseFrequencyDays(String frequency) {
    String days = StringUtils.substringBefore(frequency, "/d");
    return days;
  }

  /**
   * Static helper method to parse frequency string
   *
   * @should return number of days per weeks which is part of frequency string
   * @param frequency (format "x/d y d/w")
   * @return y
   */
  private static String parseFrequencyWeek(String frequency) {
    String temp = StringUtils.substringAfter(frequency, "/d");
    String weeks = StringUtils.substringBefore(temp, "d/");
    return weeks;
  }

  /**
   * @should return HTML snippet
   * @see HtmlGeneratorElement#generateHtml(org.openmrs.module.htmlformentry.FormEntryContext)
   */
  @Override
    public String generateHtml(FormEntryContext context) {
    StringBuilder ret = new StringBuilder();
    MessageSourceService mss = Context.getMessageSourceService();
   
    if (drugWidget != null) {
        if (drugWidget instanceof CheckboxWidget == false)
            ret.append(mss.getMessage("DrugOrder.drug") + " ");
      ret.append(drugWidget.generateHtml(context) + " ");
      if (context.getMode() != Mode.VIEW)
        ret.append(drugErrorWidget.generateHtml(context));
      ret.append(" | ");
    }
   
    ret.append(generateHtmlForAdditionalWidgets(context));
   
    if (frequencyWidget != null) {
      ret.append(mss.getMessage("DrugOrder.frequency") + " ");
      ret.append(frequencyWidget.generateHtml(context));
      if (context.getMode() != Mode.VIEW)
        ret.append(frequencyErrorWidget.generateHtml(context));
    }
    if (frequencyWeekWidget != null) {
      ret.append(" x ");
      ret.append(frequencyWeekWidget.generateHtml(context+ " ");
      if (context.getMode() != Mode.VIEW)
        ret.append(frequencyWeekErrorWidget.generateHtml(context));
    }
    if (startDateWidget != null) {
      ret.append(" | ");
      ret.append(mss.getMessage("general.dateStart") + " ");
      ret.append(startDateWidget.generateHtml(context) + " ");
      if (context.getMode() != Mode.VIEW)
        ret.append(startDateErrorWidget.generateHtml(context));
    }
    if (orderDurationWidget != null){
        ret.append(mss.getMessage("htmlformentry.general.for") + " ");
        ret.append(orderDurationWidget.generateHtml(context));
        ret.append(" " + mss.getMessage("htmlformentry.general.days") " ");
        if (context.getMode() != Mode.VIEW)
                ret.append(orderDurationErrorWidget.generateHtml(context));
    }
    //duration and discontinuedDate are now mutually exclusive
    if (discontinuedDateWidget != null) {
      ret.append(mss.getMessage("general.dateDiscontinued") + " ");
      ret.append(discontinuedDateWidget.generateHtml(context) + " ");
      if (context.getMode() != Mode.VIEW)
        ret.append(discontinuedDateErrorWidget.generateHtml(context));
    }
    if (discontinuedReasonWidget != null){
        ret.append(" | " + mss.getMessage("general.discontinuedReason") + " ");
            ret.append(discontinuedReasonWidget.generateHtml(context) + " ");
            if (context.getMode() != Mode.VIEW)
                ret.append(discontinuedReasonErrorWidget.generateHtml(context));
        }
   
    ret.append(generateHtmlForWidget(context, instructionsLabel + " ", instructionsWidget, instructionsErrorWidget));
   
    return ret.toString();
    }
 
  protected String generateHtmlForAdditionalWidgets(FormEntryContext context) {
    MessageSourceService mss = Context.getMessageSourceService();
   
      return generateHtmlForWidget(context, mss.getMessage("DrugOrder.dose") + " ", doseWidget, doseErrorWidget);
    }

  public static String generateHtmlForWidget(FormEntryContext context, String label, Widget widget, Widget errorWidget) {
    StringBuilder html = new StringBuilder();
    if (widget != null){
      if (label != null) {
        html.append(label);
      }
      html.append(widget.generateHtml(context) + " ");
        if (context.getMode() != Mode.VIEW && errorWidget != null)
          html.append(errorWidget.generateHtml(context));
    }
    return html.toString();
  }

  /**
   * handleSubmission saves a drug order if in ENTER or EDIT-mode
   * 
   * @see org.openmrs.module.htmlformentry.action.FormSubmissionControllerAction#handleSubmission(org.openmrs.module.htmlformentry.FormEntrySession, javax.servlet.http.HttpServletRequest)
   */
  @Override
    public void handleSubmission(FormEntrySession session, HttpServletRequest submission) {
    OrderTag orderTag = newOrderTag();
   
      if (drugWidget.getValue(session.getContext(), submission) != null)
              orderTag.drugId = ((String) drugWidget.getValue(session.getContext(), submission));
      orderTag.startDate =  startDateWidget.getValue(session.getContext(), submission);
      if (orderDurationWidget != null){
         String orderDurationStr = (String) orderDurationWidget.getValue(session.getContext(), submission);
         try {
             orderTag.orderDuration = Integer.valueOf(orderDurationStr);
         } catch (Exception ex){
             //pass
         }
      }
      if (discontinuedDateWidget != null){
          orderTag.discontinuedDate = discontinuedDateWidget.getValue(session.getContext(), submission);
      }   
      if (discontinuedReasonWidget != null){
          orderTag.discontinuedReasonStr = (String) discontinuedReasonWidget.getValue(session.getContext(), submission);
      }
      if (instructionsWidget != null)
          orderTag.instructions = (String) instructionsWidget.getValue(session.getContext(), submission);
      if (!StringUtils.isEmpty(orderTag.drugId) && !orderTag.drugId.equals("~")){
          orderTag.drug = Context.getConceptService().getDrug(Integer.valueOf(orderTag.drugId));
          if (defaultDose == null)
              orderTag.dose = orderTag.drug.getDoseStrength();
          else
              orderTag.dose = defaultDose;
         
          if (!hideDoseAndFrequency){
                orderTag.dose = (Double) doseWidget.getValue(session.getContext(), submission);
                orderTag.frequency = (String) frequencyWidget.getValue(session.getContext(), submission);
                if (frequencyWeekWidget != null) {
                  orderTag.frequency += "/d " + frequencyWeekWidget.getValue(session.getContext(), submission) + "d/w";
                }
            }
         
          populateOrderTag(orderTag, session, submission);
         
          if (session.getContext().getMode() == Mode.ENTER || (session.getContext().getMode() == Mode.EDIT && existingOrder == null)) {      
            enterOrder(session, orderTag);
          } else if (session.getContext().getMode() == Mode.EDIT) {
            editOrder(session, orderTag);
        }
      } else if (existingOrder != null){
           voidOrder(session);
         
      }
    }
 
  protected OrderTag newOrderTag() {
    return new OrderTag();
  }

  protected void populateOrderTag(OrderTag orderTag, FormEntrySession session, HttpServletRequest submission) {
     
    }

  protected void voidOrder(FormEntrySession session) {
      //void order
       existingOrder.setVoided(true);
       existingOrder.setVoidedBy(Context.getAuthenticatedUser());
       existingOrder.setVoidReason("Drug De-selected in " + session.getForm().getName());
    }

  protected void editOrder(FormEntrySession session, OrderTag orderTag) {
      existingOrder.setDrug(orderTag.drug);
      existingOrder.setDose(orderTag.dose);
      existingOrder.setFrequency(orderTag.frequency);
      existingOrder.setStartDate(orderTag.startDate);
      if (orderTag.orderDuration != null)
          existingOrder.setAutoExpireDate(calculateAutoExpireDate(orderTag.startDate, orderTag.orderDuration));
      if (orderTag.discontinuedDate != null){
          existingOrder.setDiscontinuedDate(orderTag.discontinuedDate);
          existingOrder.setDiscontinued(true);
      }
      if (!StringUtils.isEmpty(orderTag.discontinuedReasonStr))
          existingOrder.setDiscontinuedReason(HtmlFormEntryUtil.getConcept(orderTag.discontinuedReasonStr));
     
      existingOrder.setConcept(orderTag.drug.getConcept());   
      if (!StringUtils.isEmpty(orderTag.instructions))
          existingOrder.setInstructions((String) orderTag.instructions);
      log.debug("modifying drug order, drugId is " + orderTag.drugId + " and startDate is " + orderTag.startDate);
      existingOrder = setDiscontinueDateFromAutoExpire(existingOrder);
      session.getSubmissionActions().getCurrentEncounter().setDateChanged(new Date());
    }

  protected void enterOrder(FormEntrySession session, OrderTag orderTag) {
      DrugOrder drugOrder = new DrugOrder();
      if (drugOrder.getDateCreated() == null)
          drugOrder.setDateCreated(new Date());
      if (drugOrder.getCreator() == null)
          drugOrder.setCreator(Context.getAuthenticatedUser());
      if (drugOrder.getUuid() == null)
          drugOrder.setUuid(UUID.randomUUID().toString());
      drugOrder.setDrug(orderTag.drug);
      drugOrder.setPatient(session.getPatient());
      drugOrder.setDose(orderTag.dose);
      drugOrder.setFrequency(orderTag.frequency);
      drugOrder.setStartDate(orderTag.startDate);
      //order duration:
      if (orderTag.orderDuration != null)
          drugOrder.setAutoExpireDate(calculateAutoExpireDate(orderTag.startDate, orderTag.orderDuration));
      drugOrder.setVoided(false);
      drugOrder.setDrug(orderTag.drug);
      drugOrder.setConcept(orderTag.drug.getConcept());
      drugOrder.setOrderType(Context.getOrderService().getOrderType(OpenmrsConstants.ORDERTYPE_DRUG));
      if (!StringUtils.isEmpty(orderTag.instructions))
          drugOrder.setInstructions((String) orderTag.instructions);
      if (orderTag.discontinuedDate != null){
          drugOrder.setDiscontinuedDate(orderTag.discontinuedDate);
          drugOrder.setDiscontinued(true);
      }   
      if (!StringUtils.isEmpty(orderTag.discontinuedReasonStr))
          drugOrder.setDiscontinuedReason(HtmlFormEntryUtil.getConcept(orderTag.discontinuedReasonStr));
      log.debug("adding new drug order, drugId is " + orderTag.drugId + " and startDate is " + orderTag.startDate);
      drugOrder = setDiscontinueDateFromAutoExpire(drugOrder);
      session.getSubmissionActions().getCurrentEncounter().addOrder(drugOrder);
    }

  /**
   * @should return validation errors if doseWidget, startDateWidget or discontinuedDateWidget is invalid
   * @see org.openmrs.module.htmlformentry.action.FormSubmissionControllerAction#validateSubmission(org.openmrs.module.htmlformentry.FormEntryContext, javax.servlet.http.HttpServletRequest)
   */
  @Override
    public Collection<FormSubmissionError> validateSubmission(FormEntryContext context, HttpServletRequest submission) {

      List<FormSubmissionError> ret = new ArrayList<FormSubmissionError>();
      try {
      if (drugWidget != null && drugWidget.getValue(context, submission) != null && ((String) drugWidget.getValue(context, submission)).equals("~"))
          throw new IllegalArgumentException("htmlformentry.error.cannotChooseADrugHeader");
      } catch (Exception ex){
          ret.add(new FormSubmissionError(context
                        .getFieldName(drugErrorWidget), Context
                        .getMessageSourceService().getMessage(ex.getMessage())));
      }
      //if no drug specified, then don't do anything.
      if (drugWidget != null && drugWidget.getValue(context, submission) != null && !((String) drugWidget.getValue(context, submission)).trim().equals("") && !((String) drugWidget.getValue(context, submission)).trim().equals("~")){
          try {
            if (doseWidget != null) {
              Double dose = (Double) doseWidget.getValue(context, submission);
              if (dose == null)
                throw new Exception("htmlformentry.error.required");
             
              // min max
              if (validateDose) {
                String drugID = (String) drugWidget.getValue(context, submission);
                Drug drug = Context.getConceptService().getDrug(drugID);
                if ((drug.getMinimumDailyDose() != null && dose < drug.getMinimumDailyDose()) || (drug.getMaximumDailyDose() != null && dose > drug.getMaximumDailyDose())) {
                  throw new IllegalArgumentException("htmlformentry.error.doseOutOfRange");
                }             
              }
            }
          } catch (Exception ex) {
            ret.add(new FormSubmissionError(context
                .getFieldName(doseErrorWidget), Context
                .getMessageSourceService().getMessage(ex.getMessage())));
          }
          try {
            if (startDateWidget != null) {
              Date dateCreated = startDateWidget.getValue(context, submission);
              if (dateCreated == null)
                throw new Exception("htmlformentry.error.required");
            }
          } catch (Exception ex) {
            ret.add(new FormSubmissionError(context
                .getFieldName(startDateErrorWidget), Context
                .getMessageSourceService().getMessage(ex.getMessage())));
          }
          try {
                    if (startDateWidget != null && discontinuedDateWidget != null) {
                        Date startDate = startDateWidget.getValue(context, submission);
                        Date endDate = discontinuedDateWidget.getValue(context, submission);
                        if (startDate != null && endDate != null
                                && startDate.getTime() > endDate.getTime())
                            throw new Exception("htmlformentry.error.discontinuedDateBeforeStartDate");
                    }
                } catch (Exception ex) {
                    ret.add(new FormSubmissionError(context
                            .getFieldName(discontinuedDateErrorWidget), Context
                            .getMessageSourceService().getMessage(ex.getMessage())));
                }
                try {
                    if (discontinuedReasonWidget != null && discontinuedDateWidget != null) {
                        String discReason = (String) discontinuedReasonWidget.getValue(context, submission);
                        Date endDate = discontinuedDateWidget.getValue(context, submission);
                        if (endDate == null && !StringUtils.isEmpty(discReason))
                            throw new Exception("htmlformentry.error.discontinuedReasonEnteredWithoutDate");
                    }
                } catch (Exception ex) {
                    ret.add(new FormSubmissionError(context
                            .getFieldName(discontinuedReasonErrorWidget), Context
                            .getMessageSourceService().getMessage(ex.getMessage())));
                }
                try {
                    if (orderDurationWidget != null && orderDurationWidget.getValue(context, submission) != null) {
                        String orderDurationVal = (String) orderDurationWidget.getValue(context, submission);
                        if (!orderDurationVal.equals("")){
                            try {
                                Integer.valueOf(orderDurationVal);
                            } catch (Exception ex){
                                throw new Exception("htmlformentry.error.durationMustBeEmptyOrNumeric");
                            }
                        }   
                    }
                } catch (Exception ex) {
                    ret.add(new FormSubmissionError(context
                            .getFieldName(orderDurationErrorWidget), Context
                            .getMessageSourceService().getMessage(ex.getMessage())));
                }
      }
     
      return ret;
      }
 
  protected Date calculateAutoExpireDate(Date startDate, Integer orderDuration){
      Calendar cal = Calendar.getInstance();
      cal.setTime(startDate);
      cal.add(Calendar.DAY_OF_MONTH, orderDuration);
      return cal.getTime();
  }
 
 
  private DrugOrder setDiscontinueDateFromAutoExpire(DrugOrder dor){
      if (dor.getAutoExpireDate() != null){
          Date today = new Date();
          if (dor.getAutoExpireDate().getTime() < today.getTime()){
              dor.setDiscontinuedDate(dor.getAutoExpireDate());
              //TODO:  when discontinueReason is a String, set it.
          }   
      }
      return dor;
  }

  /* (non-Javadoc)
   * @see org.openmrs.module.htmlformentry.element.GettingExistingOrder#getExistingOrder()
   */
  @Override
  public DrugOrder getExistingOrder() {
    return existingOrder;
  }
 
  protected static class OrderTag {
     
      public String drugId;
     
      public Date startDate;
     
      public Integer orderDuration;
     
      public Date discontinuedDate;
     
      public String discontinuedReasonStr;
     
      public String instructions;
     
      public Drug drug;
     
      public Double dose;
     
      public String frequency;
    }
}
TOP

Related Classes of org.openmrs.module.htmlformentry.element.DrugOrderSubmissionElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.