org.akaza.openclinica.control.managestudy.UpdateStudyEventServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.akaza.openclinica.control.managestudy.UpdateStudyEventServlet.java

Source

/*
 * OpenClinica is distributed under the
 * GNU Lesser General Public License (GNU LGPL).
    
 * For details see: http://www.openclinica.org/license
 * copyright 2003-2005 Akaza Research
 */
package org.akaza.openclinica.control.managestudy;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.akaza.openclinica.bean.admin.CRFBean;
import org.akaza.openclinica.bean.core.DataEntryStage;
import org.akaza.openclinica.bean.core.ResolutionStatus;
import org.akaza.openclinica.bean.core.Role;
import org.akaza.openclinica.bean.core.Status;
import org.akaza.openclinica.bean.core.SubjectEventStatus;
import org.akaza.openclinica.bean.login.UserAccountBean;
import org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean;
import org.akaza.openclinica.bean.managestudy.DisplayEventDefinitionCRFBean;
import org.akaza.openclinica.bean.managestudy.DisplayStudyEventBean;
import org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean;
import org.akaza.openclinica.bean.managestudy.StudyBean;
import org.akaza.openclinica.bean.managestudy.StudyEventBean;
import org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean;
import org.akaza.openclinica.bean.managestudy.StudySubjectBean;
import org.akaza.openclinica.bean.submit.CRFVersionBean;
import org.akaza.openclinica.bean.submit.DisplayEventCRFBean;
import org.akaza.openclinica.bean.submit.EventCRFBean;
import org.akaza.openclinica.control.SpringServletAccess;
import org.akaza.openclinica.control.core.SecureController;
import org.akaza.openclinica.control.form.DiscrepancyValidator;
import org.akaza.openclinica.control.form.FormDiscrepancyNotes;
import org.akaza.openclinica.control.form.FormProcessor;
import org.akaza.openclinica.control.form.Validator;
import org.akaza.openclinica.control.submit.AddNewSubjectServlet;
import org.akaza.openclinica.control.submit.SubmitDataServlet;
import org.akaza.openclinica.core.form.StringUtil;
import org.akaza.openclinica.dao.admin.CRFDAO;
import org.akaza.openclinica.dao.hibernate.RuleSetDao;
import org.akaza.openclinica.dao.managestudy.DiscrepancyNoteDAO;
import org.akaza.openclinica.dao.managestudy.EventDefinitionCRFDAO;
import org.akaza.openclinica.dao.managestudy.StudyDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO;
import org.akaza.openclinica.dao.managestudy.StudySubjectDAO;
import org.akaza.openclinica.dao.rule.RuleSetDAO;
import org.akaza.openclinica.dao.submit.CRFVersionDAO;
import org.akaza.openclinica.dao.submit.EventCRFDAO;
import org.akaza.openclinica.dao.submit.ItemDataDAO;
import org.akaza.openclinica.domain.rule.RuleSetBean;
import org.akaza.openclinica.i18n.util.ResourceBundleProvider;
import org.akaza.openclinica.service.Auth0UserService;
import org.akaza.openclinica.service.Auth0UserServiceImpl;
import org.akaza.openclinica.service.DiscrepancyNoteUtil;
import org.akaza.openclinica.service.rule.RuleSetService;
import org.akaza.openclinica.view.Page;
import org.akaza.openclinica.web.InsufficientPermissionException;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * @author jxu
 *
 *         Performs updating study event action
 */
public class UpdateStudyEventServlet extends SecureController {
    public static final String EVENT_ID = "event_id";

    public static final String STUDY_SUBJECT_ID = "ss_id";

    public static final String EVENT_BEAN = "studyEvent";

    public static final String EVENT_DEFINITION_BEAN = "eventDefinition";

    public static final String SUBJECT_EVENT_STATUS_ID = "statusId";

    public static final String INPUT_STARTDATE_PREFIX = "start";

    // YW, 3-12-2008, for 2220 fix <<
    public static final String INPUT_ENDDATE_PREFIX = "end";
    // YW >>

    public static final String INPUT_LOCATION = "location";

    public final static String HAS_LOCATION_NOTE = "hasLocationNote";
    public final static String LOCATION_NOTE = "locationNote";
    public final static String HAS_START_DATE_NOTE = "hasStartDateNote";
    public final static String START_DATE_NOTE = "startDateNote";
    public final static String HAS_END_DATE_NOTE = "hasEndDateNote";
    public final static String END_DATE_NOTE = "endDateNote";
    private WebApplicationContext ctx = null;
    public static final String ORIGINATING_PAGE = "originatingPage";

    @Override
    public void mayProceed() throws InsufficientPermissionException {

        if (SubmitDataServlet.maySubmitData(ub, currentRole)) {
            return;
        }

        addPageMessage(respage.getString("no_have_correct_privilege_current_study") + " "
                + respage.getString("change_active_study_or_contact"));
        throw new InsufficientPermissionException(Page.MENU_SERVLET, resexception.getString("not_study_director"),
                "1");

    }

    @Override
    public void processRequest() throws Exception {
        ctx = WebApplicationContextUtils.getWebApplicationContext(context);

        FormDiscrepancyNotes discNotes = null;
        FormProcessor fp = new FormProcessor(request);
        int studyEventId = fp.getInt(EVENT_ID, true);
        int studySubjectId = fp.getInt(STUDY_SUBJECT_ID, true);

        String module = fp.getString(MODULE);
        request.setAttribute(MODULE, module);

        String fromResolvingNotes = fp.getString("fromResolvingNotes", true);
        if (StringUtil.isBlank(fromResolvingNotes)) {
            session.removeAttribute(ViewNotesServlet.WIN_LOCATION);
            session.removeAttribute(ViewNotesServlet.NOTES_TABLE);
            checkStudyLocked(Page.MANAGE_STUDY, respage.getString("current_study_locked"));
            checkStudyFrozen(Page.MANAGE_STUDY, respage.getString("current_study_frozen"));
        }

        if (studyEventId == 0 || studySubjectId == 0) {
            addPageMessage(respage.getString("choose_a_study_event_to_edit"));
            request.setAttribute("id", new Integer(studySubjectId).toString());
            forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET);
            return;
        }

        StudySubjectDAO ssdao = new StudySubjectDAO(sm.getDataSource());
        StudySubjectBean ssub = null;
        if (studySubjectId > 0) {
            ssub = (StudySubjectBean) ssdao.findByPK(studySubjectId);
            request.setAttribute("studySubject", ssub);
            request.setAttribute("id", studySubjectId + "");// for the workflow
            // box, so it can
            // link back to view
            // study subject
        }
        // YW 11-07-2007, a study event could not be updated if its study
        // subject has been removed
        // Status s = ((StudySubjectBean)new
        // StudySubjectDAO(sm.getDataSource()).findByPK(studySubjectId)).getStatus();
        Status s = ssub.getStatus();
        if ("removed".equalsIgnoreCase(s.getName()) || "auto-removed".equalsIgnoreCase(s.getName())) {
            addPageMessage(resword.getString("study_event") + resterm.getString("could_not_be")
                    + resterm.getString("updated") + "." + respage.getString("study_subject_has_been_deleted"));
            request.setAttribute("id", new Integer(studySubjectId).toString());
            forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET);
        }
        // YW

        request.setAttribute(STUDY_SUBJECT_ID, new Integer(studySubjectId).toString());
        StudyEventDAO sedao = new StudyEventDAO(sm.getDataSource());
        EventCRFDAO ecrfdao = new EventCRFDAO(sm.getDataSource());

        StudyEventBean studyEvent = (StudyEventBean) sedao.findByPK(studyEventId);

        studyEvent.setEventCRFs(ecrfdao.findAllByStudyEvent(studyEvent));

        // only owner, admins, and study director/coordinator can update
        // if (ub.getId() != studyEvent.getOwnerId()) {
        // if (!ub.isSysAdmin() &&
        // !currentRole.getRole().equals(Role.STUDYDIRECTOR)
        // && !currentRole.getRole().equals(Role.COORDINATOR)) {
        // addPageMessage(respage.getString("no_have_correct_privilege_current_study")
        // + respage.getString("change_study_contact_sysadmin"));
        // request.setAttribute("id", new Integer(studySubjectId).toString());
        // forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET);
        // return;
        // }
        // }
        // above removed tbh 11162007

        ArrayList statuses = SubjectEventStatus.toArrayList();
        // remove more statuses here, tbh, 092007
        // ### updates to status setting, below added tbh 102007
        // following pieces of logic to be added:
        /*
         * REMOVED can happen at any step, COMPLETED can happen if the Subject
         * Event is already complete, COMPLETED can also happen if all required
         * CRFs in the Subject Event are completed, LOCKED can occur when all
         * Event CRFs are completed, or not started, or removed, LOCKED/REMOVED
         * are only options, however, when the user is study director or study
         * coordinator SKIPPED/STOPPED? Additional rules spelled out on Nov 16
         * 2007: STOPPED should only be in the list of choices after IDE has
         * been started, i.e. not when SCHEDULED SKIPPED should only be in the
         * list before IDE has been started, i.e. when SCHEDULED reminder about
         * LOCKED happening only when CRFs are completed (not as in the
         * above...) if a status is LOCKED already, it should allow a user to
         * set the event back to COMPLETED
         */

        StudyDAO sdao = new StudyDAO(this.sm.getDataSource());
        StudyBean studyBean = (StudyBean) sdao.findByPK(ssub.getStudyId());
        checkRoleByUserAndStudy(ub, studyBean, sdao);
        // To remove signed status from the list
        EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(sm.getDataSource());
        boolean removeSign = false;
        // DiscrepancyNoteDAO discDao = new
        // DiscrepancyNoteDAO(sm.getDataSource());
        ArrayList eventCrfs = studyEvent.getEventCRFs();
        for (int i = 0; i < eventCrfs.size(); i++) {
            EventCRFBean ecrf = (EventCRFBean) eventCrfs.get(i);
            EventDefinitionCRFBean edcBean = edcdao.findByStudyEventIdAndFormLayoutId(studyBean, studyEventId,
                    ecrf.getFormLayoutId());
            if (ecrf.getStage().equals(DataEntryStage.INITIAL_DATA_ENTRY)
                    || ecrf.getStage().equals(DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE)
                            && edcBean.isDoubleEntry() == true) {
                removeSign = true;
                break;
            }
        }

        if (currentRole.isResearchAssistant()) {
            removeSign = true;
        }
        if (currentRole.isResearchAssistant2()) {
            removeSign = true;
        }

        if (removeSign == true || !currentRole.isInvestigator()) {
            statuses.remove(SubjectEventStatus.SIGNED);
        }
        // ///End of remove signed status from the list

        // BWP: 2735>>keep the DATA_ENTRY_STARTED status
        /*
         * if(!studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.
         * DATA_ENTRY_STARTED)) {
         * statuses.remove(SubjectEventStatus.DATA_ENTRY_STARTED);
         * //statuses.remove(SubjectEventStatus.SKIPPED); // per new rule
         * 11-2007 }
         */
        if (!studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.NOT_SCHEDULED)) {
            statuses.remove(SubjectEventStatus.NOT_SCHEDULED);
        }
        if (!studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.SCHEDULED)) {
            // can't lock a non-completed CRF, but removed above
            statuses.remove(SubjectEventStatus.SCHEDULED);
            // statuses.remove(SubjectEventStatus.SKIPPED);
            // addl rule: skipped should only be present before data starts
            // being entered
        }
        if (studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.DATA_ENTRY_STARTED)) {
            statuses.remove(SubjectEventStatus.SKIPPED);
        }
        if ((studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.SCHEDULED)
                || studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.DATA_ENTRY_STARTED))
                && currentRole.isInvestigator()) {
            statuses.remove(SubjectEventStatus.SIGNED);
        }

        ArrayList getECRFs = studyEvent.getEventCRFs();
        // above removed tbh 102007, require to get all definitions, no matter
        // if they are filled in or now
        EventDefinitionCRFDAO edefcrfdao = new EventDefinitionCRFDAO(sm.getDataSource());
        ArrayList getAllECRFs = (ArrayList) edefcrfdao.findAllByDefinition(studyBean,
                studyEvent.getStudyEventDefinitionId());
        // does the study event have all complete CRFs which are required?
        logger.debug("found number of ecrfs: " + getAllECRFs.size());
        // may not be populated, only entered crfs seem to ping the list
        for (int u = 0; u < getAllECRFs.size(); u++) {
            EventDefinitionCRFBean ecrfBean = (EventDefinitionCRFBean) getAllECRFs.get(u);

            //
            logger.debug("found number of existing ecrfs: " + getECRFs.size());
            if (getECRFs.size() == 0) {
                statuses.remove(SubjectEventStatus.COMPLETED);
                statuses.remove(SubjectEventStatus.LOCKED);

            } // otherwise...
            for (int uv = 0; uv < getECRFs.size(); uv++) {
                EventCRFBean existingBean = (EventCRFBean) getECRFs.get(uv);
                logger.debug("***** found: " + existingBean.getCRFVersionId() + " " + existingBean.getCrf().getId()
                        + " " + existingBean.getCrfVersion().getName() + " " + existingBean.getStatus().getName()
                        + " " + existingBean.getStage().getName());

                logger.debug(
                        "***** comparing above to ecrfBean.DefaultVersionID: " + ecrfBean.getDefaultVersionId());

                // if (existingBean.getCRFVersionId() ==
                // ecrfBean.getDefaultVersionId()) {
                // OK. this only works if we go ahead and remove the drop down
                // will this match up? Do we need to pull it out of
                // studyEvent.getEventCRFs()?
                // only case that this will screw up is if there are no crfs
                // whatsoever
                // this is addressed in the if-clause above
                if (!existingBean.getStatus().equals(Status.UNAVAILABLE)
                        && edefcrfdao.isRequiredInDefinition(existingBean.getCRFVersionId(), studyEvent)) {

                    logger.debug("found that " + existingBean.getCrfVersion().getName() + " is required...");
                    // that is, it's not completed but required to complete
                    statuses.remove(SubjectEventStatus.COMPLETED);
                    statuses.remove(SubjectEventStatus.LOCKED);
                    // per new rule above 11-16-2007
                }
                // }
            }
        }
        // below added 092007, tbh, task #1390
        if (!ub.isSysAdmin() && !currentRole.getRole().equals(Role.STUDYDIRECTOR)
                && !currentRole.getRole().equals(Role.COORDINATOR)) {
            statuses.remove(SubjectEventStatus.LOCKED);
        }

        // also, if data entry is started, can't move back to scheduled or not
        // scheduled
        if (studyEvent.getSubjectEventStatus().equals(SubjectEventStatus.DATA_ENTRY_STARTED)) {
            statuses.remove(SubjectEventStatus.NOT_SCHEDULED);
            statuses.remove(SubjectEventStatus.SCHEDULED);
        }

        // ### tbh, above modified 102007
        request.setAttribute("statuses", statuses);

        String action = fp.getString("action");
        StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(sm.getDataSource());
        StudyEventDefinitionBean sed = (StudyEventDefinitionBean) seddao
                .findByPK(studyEvent.getStudyEventDefinitionId());
        request.setAttribute(EVENT_DEFINITION_BEAN, sed);

        String start_date = fp.getDateTimeInputString(INPUT_STARTDATE_PREFIX);
        String end_date = fp.getDateTimeInputString(INPUT_ENDDATE_PREFIX);
        SimpleDateFormat dteFormat = new SimpleDateFormat(
                ResourceBundleProvider.getFormatBundle().getString("date_format_string"));
        Date start = null;
        Date end = null;
        if (!StringUtils.isEmpty(start_date)) {
            start = fp.getDateTime(INPUT_STARTDATE_PREFIX);
            start_date = dteFormat.format(start);
        }
        if (!StringUtils.isEmpty(end_date)) {
            end = fp.getDateTime(INPUT_ENDDATE_PREFIX);
            end_date = dteFormat.format(end);
        }

        if (action.equalsIgnoreCase("submit")) {
            discNotes = (FormDiscrepancyNotes) session
                    .getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
            DiscrepancyValidator v = new DiscrepancyValidator(request, discNotes);
            SubjectEventStatus ses = SubjectEventStatus.get(fp.getInt(SUBJECT_EVENT_STATUS_ID));
            studyEvent.setSubjectEventStatus(ses);
            EventCRFDAO ecdao = new EventCRFDAO(sm.getDataSource());
            ArrayList<EventCRFBean> eventCRFs = ecdao.findAllByStudyEvent(studyEvent);
            if (ses.equals(SubjectEventStatus.SKIPPED) || ses.equals(SubjectEventStatus.STOPPED)) {
                studyEvent.setStatus(Status.UNAVAILABLE);
                for (int i = 0; i < eventCRFs.size(); i++) {
                    EventCRFBean ecb = eventCRFs.get(i);
                    ecb.setOldStatus(ecb.getStatus());
                    ecb.setStatus(Status.UNAVAILABLE);
                    ecb.setUpdater(ub);
                    ecb.setUpdatedDate(new Date());
                    ecdao.update(ecb);
                }
            } else {
                for (int i = 0; i < eventCRFs.size(); i++) {
                    EventCRFBean ecb = eventCRFs.get(i);
                    ecb.setUpdater(ub);
                    ecb.setUpdatedDate(new Date());
                    ecdao.update(ecb);
                }
            }
            // YW 3-12-2008, 2220 fix
            String strEnd = fp.getDateTimeInputString(INPUT_ENDDATE_PREFIX);
            String strEndScheduled = fp.getDateTimeInputString(INPUT_ENDDATE_PREFIX);
            String strStartScheduled = fp.getDateTimeInputString(INPUT_STARTDATE_PREFIX);

            if (!strStartScheduled.equals("")) {
                v.addValidation(INPUT_STARTDATE_PREFIX, Validator.IS_DATE_TIME);
                v.alwaysExecuteLastValidation(INPUT_STARTDATE_PREFIX);
            }
            if (!strEndScheduled.equals("")) {
                v.addValidation(INPUT_ENDDATE_PREFIX, Validator.IS_DATE_TIME);
                v.alwaysExecuteLastValidation(INPUT_ENDDATE_PREFIX);
            }
            // v.addValidation(INPUT_LOCATION, Validator.NO_BLANKS); Disable validation on location, location can be
            // empty when updating a study event
            HashMap errors = v.validate();
            // YW, 3-12-2008, 2220 fix <<
            if (!strEnd.equals("") && !errors.containsKey(INPUT_STARTDATE_PREFIX)
                    && !errors.containsKey(INPUT_ENDDATE_PREFIX)) {
                end = fp.getDateTime(INPUT_ENDDATE_PREFIX);
                if (!fp.getString(INPUT_STARTDATE_PREFIX + "Date")
                        .equals(fp.getString(INPUT_ENDDATE_PREFIX + "Date"))) {
                    if (end.before(start)) {
                        v.addError(errors, INPUT_ENDDATE_PREFIX,
                                resexception.getString("input_provided_not_occure_after_previous_start_date_time"));
                    }
                } else {
                    // if in same date, only check when both had time entered
                    if (fp.timeEntered(INPUT_STARTDATE_PREFIX) && fp.timeEntered(INPUT_ENDDATE_PREFIX)) {
                        if (end.before(start) || end.equals(start)) {
                            v.addError(errors, INPUT_ENDDATE_PREFIX, resexception
                                    .getString("input_provided_not_occure_after_previous_start_date_time"));
                        }
                    }
                }
            }
            // YW >>

            if (!errors.isEmpty()) {
                setInputMessages(errors);
                String prefixes[] = { INPUT_STARTDATE_PREFIX, INPUT_ENDDATE_PREFIX };
                fp.setCurrentDateTimeValuesAsPreset(prefixes);
                setPresetValues(fp.getPresetValues());

                studyEvent.setLocation(fp.getString(INPUT_LOCATION));

                request.setAttribute("changeDate", fp.getString("changeDate"));
                request.setAttribute(EVENT_BEAN, studyEvent);
                forwardPage(Page.UPDATE_STUDY_EVENT);

            } else if (studyEvent.getSubjectEventStatus().isSigned()) {
                // Checks if the status is signed
                // -----------------
                request.setAttribute(STUDY_SUBJECT_ID, new Integer(studySubjectId).toString());
                if (fp.getString(INPUT_STARTDATE_PREFIX + "Hour").equals("-1")
                        && fp.getString(INPUT_STARTDATE_PREFIX + "Minute").equals("-1")
                        && fp.getString(INPUT_STARTDATE_PREFIX + "Half").equals("")) {
                    studyEvent.setStartTimeFlag(false);
                } else {
                    studyEvent.setStartTimeFlag(true);
                }
                studyEvent.setDateStarted(start);

                if (!strEnd.equals("")) {
                    studyEvent.setDateEnded(end);
                    if (fp.getString(INPUT_ENDDATE_PREFIX + "Hour").equals("-1")
                            && fp.getString(INPUT_ENDDATE_PREFIX + "Minute").equals("-1")
                            && fp.getString(INPUT_ENDDATE_PREFIX + "Half").equals("")) {
                        studyEvent.setEndTimeFlag(false);
                    } else {
                        studyEvent.setEndTimeFlag(true);
                    }
                }

                studyEvent.setLocation(fp.getString(INPUT_LOCATION));
                studyEvent.setStudyEventDefinition(sed);
                // -------------------
                ssdao = new StudySubjectDAO(sm.getDataSource());
                StudySubjectBean ssb = (StudySubjectBean) ssdao.findByPK(studyEvent.getStudySubjectId());

                ecdao = new EventCRFDAO(sm.getDataSource());
                eventCRFs = ecdao.findAllByStudyEvent(studyEvent);
                ArrayList<Boolean> doRuleSetsExist = new ArrayList<Boolean>();
                RuleSetDAO ruleSetDao = new RuleSetDAO(sm.getDataSource());

                StudyBean study = (StudyBean) sdao.findByPK(ssb.getStudyId());
                ArrayList eventDefinitionCRFs = (ArrayList) edcdao.findAllActiveByEventDefinitionId(study,
                        studyEvent.getStudyEventDefinitionId());

                ArrayList uncompletedEventDefinitionCRFs = getUncompletedCRFs(eventDefinitionCRFs, eventCRFs);
                populateUncompletedCRFsWithCRFAndVersions(uncompletedEventDefinitionCRFs);

                ArrayList displayEventCRFs = ViewStudySubjectServlet.getDisplayEventCRFs(sm.getDataSource(),
                        eventCRFs, eventDefinitionCRFs, ub, currentRole, studyEvent.getSubjectEventStatus(), study);

                request.setAttribute("studySubject", ssb);
                request.setAttribute("uncompletedEventDefinitionCRFs", uncompletedEventDefinitionCRFs);
                request.setAttribute("displayEventCRFs", displayEventCRFs);

                request.setAttribute(EVENT_BEAN, studyEvent);
                session.setAttribute("eventSigned", studyEvent);

                DiscrepancyNoteUtil discNoteUtil = new DiscrepancyNoteUtil();
                DisplayStudyEventBean displayEvBean = new DisplayStudyEventBean();
                List<DisplayStudyEventBean> displayEvents = new ArrayList<DisplayStudyEventBean>();
                // Set up a Map for the JSP view, mapping the eventCRFId to
                // another Map: the
                // inner Map maps the resolution status name to the number of
                // notes for that
                // eventCRF id, as in New --> 2
                displayEvBean.setDisplayEventCRFs(displayEventCRFs);
                displayEvBean.setStudyEvent(studyEvent);
                displayEvents.add(displayEvBean);
                // Don't filter for res status or disc note type; disc note
                // beans are returned with eventCRFId set
                discNoteUtil.injectParentDiscNotesIntoDisplayStudyEvents(displayEvents, new HashSet(),
                        sm.getDataSource(), 0);
                Map discNoteByEventCRFid = discNoteUtil.createDiscNoteMapByEventCRF(displayEvents);
                request.setAttribute("discNoteByEventCRFid", discNoteByEventCRFid);
                session.setAttribute("signatureURL", request.getRequestURL());

                String originationUrl = "UpdateStudyEvent?action=" + action + "%26event_id=" + studyEventId
                        + "%26ss_id=" + studySubjectId + "%26startDate=" + start_date + "%26startHour="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Hour") + "%26startMinute="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Minute") + "%26startHalf="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Half") + "%26endDate=" + end_date + "%26endHour="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Hour") + "%26endMinute="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Minute") + "%26endHalf="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Half") + "%26statusId="
                        + studyEvent.getSubjectEventStatus().getId();

                request.setAttribute(ORIGINATING_PAGE, originationUrl);

                // response.sendRedirect(request.getContextPath() + "/pages/userSignature");
                forwardPage(Page.UPDATE_STUDY_EVENT_SIGNED);
            } else {
                logger.debug("no validation error");
                // YW 08-17-2007 << update start_time_flag column
                if (fp.getString(INPUT_STARTDATE_PREFIX + "Hour").equals("-1")
                        && fp.getString(INPUT_STARTDATE_PREFIX + "Minute").equals("-1")
                        && fp.getString(INPUT_STARTDATE_PREFIX + "Half").equals("")) {
                    studyEvent.setStartTimeFlag(false);
                } else {
                    studyEvent.setStartTimeFlag(true);
                }
                // YW >>
                studyEvent.setDateStarted(start);
                // YW, 3-12-2008, 2220 fix which adding End datetime <<
                if (!strEnd.equals("")) {
                    studyEvent.setDateEnded(end);
                    if (fp.getString(INPUT_ENDDATE_PREFIX + "Hour").equals("-1")
                            && fp.getString(INPUT_ENDDATE_PREFIX + "Minute").equals("-1")
                            && fp.getString(INPUT_ENDDATE_PREFIX + "Half").equals("")) {
                        studyEvent.setEndTimeFlag(false);
                    } else {
                        studyEvent.setEndTimeFlag(true);
                    }
                }
                // YW >>
                studyEvent.setLocation(fp.getString(INPUT_LOCATION));

                logger.debug("update study event and discrepancy notes...");
                studyEvent.setUpdater(ub);
                studyEvent.setUpdatedDate(new Date());
                updateClosedQueriesForUpdatedStudySubjectFields(studyEvent);
                StudyEventBean updatedStudyEvent = (StudyEventBean) sedao.update(studyEvent);

                // save discrepancy notes into DB
                FormDiscrepancyNotes fdn = (FormDiscrepancyNotes) session
                        .getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
                DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(sm.getDataSource());

                AddNewSubjectServlet.saveFieldNotes(INPUT_LOCATION, fdn, dndao, studyEvent.getId(), "studyEvent",
                        currentStudy);
                AddNewSubjectServlet.saveFieldNotes(INPUT_STARTDATE_PREFIX, fdn, dndao, studyEvent.getId(),
                        "studyEvent", currentStudy);
                AddNewSubjectServlet.saveFieldNotes(INPUT_ENDDATE_PREFIX, fdn, dndao, studyEvent.getId(),
                        "studyEvent", currentStudy);

                // getRuleSetService().runRulesInBeanProperty(createRuleSet(ssub,sed),currentStudy,ub,request,ssub);

                addPageMessage(respage.getString("study_event_updated"));
                request.setAttribute("id", new Integer(studySubjectId).toString());
                session.removeAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
                forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET);
                // FORWARD SHOULD BE TO THE NEW PAGE
            }
        } else if (action.equalsIgnoreCase("confirm")) {// confirming the signed
            // status
            String username = request.getParameter("j_user");
            String password = request.getParameter("j_pass");
            if (username == null)
                username = "";
            if (password == null)
                password = "";

            // tring encodedUserPass =
            // org.akaza.openclinica.core.SecurityManager.getInstance().encrytPassword(password);
            UserAccountBean ub = (UserAccountBean) session.getAttribute("userBean");
            StudyEventBean seb = (StudyEventBean) session.getAttribute("eventSigned");
            Auth0UserService auth0UserService = ctx.getBean("auth0UserService", Auth0UserServiceImpl.class);
            boolean isAuthenticated = auth0UserService.authenticateAuth0User(username, password);
            if (isAuthenticated && ub.getName().equals(username)) {
                Date date = new Date();
                seb.setUpdater(ub);
                seb.setUpdatedDate(date);
                seb.setAttestation("The eCRFs that are part of this event were signed by " + ub.getFirstName() + " "
                        + ub.getLastName() + " (" + ub.getName() + ") " + "on Date Time " + date
                        + " under the following attestation:\n\n" + resword.getString("sure_to_sign_subject3"));
                sedao.update(seb);

                // If all the StudyEvents become signed we will make the
                // StudySubject signed as well
                List studyEvents = sedao.findAllByStudySubject(ssub);
                boolean allSigned = true;
                for (Iterator iterator = studyEvents.iterator(); iterator.hasNext();) {
                    StudyEventBean temp = (StudyEventBean) iterator.next();
                    if (!temp.getSubjectEventStatus().equals(SubjectEventStatus.SIGNED)) {
                        allSigned = false;
                        break;
                    }
                }
                if (allSigned) {
                    logger.debug("Signing StudySubject [" + ssub.getSubjectId() + "]");
                    ssub.setStatus(Status.SIGNED);
                    ssub.setUpdater(ub);
                    ssdao.update(ssub);
                }

                // save discrepancy notes into DB
                FormDiscrepancyNotes fdn = (FormDiscrepancyNotes) session
                        .getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
                DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(sm.getDataSource());

                AddNewSubjectServlet.saveFieldNotes(INPUT_LOCATION, fdn, dndao, studyEvent.getId(), "studyEvent",
                        currentStudy);
                AddNewSubjectServlet.saveFieldNotes(INPUT_STARTDATE_PREFIX, fdn, dndao, studyEvent.getId(),
                        "studyEvent", currentStudy);
                AddNewSubjectServlet.saveFieldNotes(INPUT_ENDDATE_PREFIX, fdn, dndao, studyEvent.getId(),
                        "studyEvent", currentStudy);

                session.removeAttribute("eventSigned");
                request.setAttribute("id", new Integer(studySubjectId).toString());
                addPageMessage(respage.getString("study_event_updated"));
                forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET);
            } else {
                request.setAttribute(STUDY_SUBJECT_ID, new Integer(studySubjectId).toString());
                request.setAttribute("studyEvent", seb);
                // -------------------
                ssdao = new StudySubjectDAO(sm.getDataSource());
                StudySubjectBean ssb = (StudySubjectBean) ssdao.findByPK(studyEvent.getStudySubjectId());

                // prepare to figure out what the display should look like
                EventCRFDAO ecdao = new EventCRFDAO(sm.getDataSource());
                ArrayList<EventCRFBean> eventCRFs = ecdao.findAllByStudyEvent(studyEvent);
                ArrayList<Boolean> doRuleSetsExist = new ArrayList<Boolean>();
                RuleSetDAO ruleSetDao = new RuleSetDAO(sm.getDataSource());

                StudyBean study = (StudyBean) sdao.findByPK(ssb.getStudyId());
                ArrayList eventDefinitionCRFs = (ArrayList) edcdao.findAllActiveByEventDefinitionId(study,
                        studyEvent.getStudyEventDefinitionId());

                ArrayList uncompletedEventDefinitionCRFs = getUncompletedCRFs(eventDefinitionCRFs, eventCRFs);
                populateUncompletedCRFsWithCRFAndVersions(uncompletedEventDefinitionCRFs);

                ArrayList<DisplayEventCRFBean> displayEventCRFs = ViewStudySubjectServlet.getDisplayEventCRFs(
                        sm.getDataSource(), eventCRFs, eventDefinitionCRFs, ub, currentRole,
                        studyEvent.getSubjectEventStatus(), study);

                DiscrepancyNoteUtil discNoteUtil = new DiscrepancyNoteUtil();
                DisplayStudyEventBean displayEvBean = new DisplayStudyEventBean();
                List<DisplayStudyEventBean> displayEvents = new ArrayList<DisplayStudyEventBean>();
                displayEvBean.setDisplayEventCRFs(displayEventCRFs);
                displayEvBean.setStudyEvent(studyEvent);
                displayEvents.add(displayEvBean);
                discNoteUtil.injectParentDiscNotesIntoDisplayStudyEvents(displayEvents, new HashSet(),
                        sm.getDataSource(), 0);
                Map discNoteByEventCRFid = discNoteUtil.createDiscNoteMapByEventCRF(displayEvents);
                request.setAttribute("discNoteByEventCRFid", discNoteByEventCRFid);
                request.setAttribute("studySubject", ssb);
                request.setAttribute("uncompletedEventDefinitionCRFs", uncompletedEventDefinitionCRFs);
                request.setAttribute("displayEventCRFs", displayEventCRFs);

                // ------------------
                request.setAttribute("studyEvent", session.getAttribute("eventSigned"));
                addPageMessage(restext.getString("password_match"));

                String originationUrl = "UpdateStudyEvent?action=" + action + "%26event_id=" + studyEventId
                        + "%26ss_id=" + studySubjectId + "%26startDate=" + start_date + "%26startHour="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Hour") + "%26startMinute="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Minute") + "%26startHalf="
                        + fp.getString(INPUT_STARTDATE_PREFIX + "Half") + "%26endDate=" + end_date + "%26endHour="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Hour") + "%26endMinute="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Minute") + "%26endHalf="
                        + fp.getString(INPUT_ENDDATE_PREFIX + "Half") + "%26statusId="
                        + studyEvent.getSubjectEventStatus().getId();

                request.setAttribute(ORIGINATING_PAGE, originationUrl);
                forwardPage(Page.UPDATE_STUDY_EVENT_SIGNED);
            }
        } else {
            logger.debug("no action, go to update page");

            DiscrepancyNoteDAO discrepancyNoteDAO = new DiscrepancyNoteDAO(sm.getDataSource());
            StudySubjectBean studySubjectBean = (StudySubjectBean) ssdao.findByPK(studyEvent.getStudySubjectId());
            int studyId = studySubjectBean.getStudyId();
            boolean subjectStudyIsCurrentStudy = studyId == currentStudy.getId();
            boolean isParentStudy = studyBean.getParentStudyId() < 1;

            ArrayList<DiscrepancyNoteBean> allNotesforSubjectAndEvent = new ArrayList<DiscrepancyNoteBean>();
            allNotesforSubjectAndEvent = discrepancyNoteDAO.findExistingNoteForStudyEvent(studyEvent);

            if (!allNotesforSubjectAndEvent.isEmpty()) {
                setRequestAttributesForNotes(allNotesforSubjectAndEvent);
            }

            HashMap presetValues = new HashMap();
            // YW 08-17-2007 <<
            if (studyEvent.getDateStarted() != null) {
                if (studyEvent.getStartTimeFlag() == true) {
                    Calendar c = new GregorianCalendar();
                    c.setTime(studyEvent.getDateStarted());
                    presetValues.put(INPUT_STARTDATE_PREFIX + "Hour", new Integer(c.get(Calendar.HOUR_OF_DAY)));
                    presetValues.put(INPUT_STARTDATE_PREFIX + "Minute", new Integer(c.get(Calendar.MINUTE)));
                    // Later it could be put to somewhere as a static method if
                    // necessary.
                    switch (c.get(Calendar.AM_PM)) {
                    case 0:
                        presetValues.put(INPUT_STARTDATE_PREFIX + "Half", "am");
                        break;
                    case 1:
                        presetValues.put(INPUT_STARTDATE_PREFIX + "Half", "pm");
                        break;
                    default:
                        presetValues.put(INPUT_STARTDATE_PREFIX + "Half", "");
                        break;
                    }
                } else {
                    presetValues.put(INPUT_STARTDATE_PREFIX + "Hour", new Integer(-1));
                    presetValues.put(INPUT_STARTDATE_PREFIX + "Minute", new Integer(-1));
                    presetValues.put(INPUT_STARTDATE_PREFIX + "Half", "");
                }

                // YW >>

                String dateValue = local_df.format(studyEvent.getDateStarted());
                presetValues.put(INPUT_STARTDATE_PREFIX + "Date", dateValue);

                // YW 3-12-2008, add end datetime for 2220 fix<<
                presetValues.put(INPUT_ENDDATE_PREFIX + "Hour", new Integer(-1));
                presetValues.put(INPUT_ENDDATE_PREFIX + "Minute", new Integer(-1));
                presetValues.put(INPUT_ENDDATE_PREFIX + "Half", "");
            }
            if (studyEvent.getDateEnded() != null) {
                if (studyEvent.getEndTimeFlag() == true) {
                    Calendar c = new GregorianCalendar();
                    c.setTime(studyEvent.getDateEnded());
                    presetValues.put(INPUT_ENDDATE_PREFIX + "Hour", new Integer(c.get(Calendar.HOUR_OF_DAY)));
                    presetValues.put(INPUT_ENDDATE_PREFIX + "Minute", new Integer(c.get(Calendar.MINUTE)));
                    // Later it could be put to somewhere as a static method if
                    // necessary.
                    switch (c.get(Calendar.AM_PM)) {
                    case 0:
                        presetValues.put(INPUT_ENDDATE_PREFIX + "Half", "am");
                        break;
                    case 1:
                        presetValues.put(INPUT_ENDDATE_PREFIX + "Half", "pm");
                        break;
                    default:
                        presetValues.put(INPUT_ENDDATE_PREFIX + "Half", "");
                        break;
                    }
                }
                presetValues.put(INPUT_ENDDATE_PREFIX + "Date", local_df.format(studyEvent.getDateEnded()));
            }
            // YW >>

            setPresetValues(presetValues);

            request.setAttribute("studyEvent", studyEvent);
            request.setAttribute("studySubject", studySubjectBean);

            discNotes = new FormDiscrepancyNotes();
            session.setAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME, discNotes);

            forwardPage(Page.UPDATE_STUDY_EVENT);
        } // else

    }

    private void updateClosedQueriesForUpdatedStudySubjectFields(StudyEventBean updatedStudyEvent) {
        StudyEventDAO seDAO = new StudyEventDAO(sm.getDataSource());
        StudyEventBean existingStudyEvent = (StudyEventBean) seDAO.findByPK(updatedStudyEvent.getId());
        DiscrepancyNoteDAO dnDAO = new DiscrepancyNoteDAO(sm.getDataSource());
        List<DiscrepancyNoteBean> existingNotes = dnDAO.findExistingNoteForStudyEvent(existingStudyEvent);

        for (DiscrepancyNoteBean existingNote : existingNotes) {
            if (existingNote.getColumn().equals("start_date")
                    && existingNote.getResStatus().equals(ResolutionStatus.CLOSED) && existingStudyEvent
                            .getDateStarted().getTime() != updatedStudyEvent.getDateStarted().getTime()) {
                existingNote.setResolutionStatusId(ResolutionStatus.CLOSED_MODIFIED.getId());
                DiscrepancyNoteBean childNote = createChildNote(existingNote);
                dnDAO.create(childNote);
                dnDAO.createMapping(childNote);
                dnDAO.update(existingNote);
            }

            if (existingNote.getColumn().equals("end_date")
                    && existingNote.getResStatus().equals(ResolutionStatus.CLOSED)
                    && existingStudyEvent.getDateEnded().getTime() != updatedStudyEvent.getDateEnded().getTime()) {
                existingNote.setResolutionStatusId(ResolutionStatus.CLOSED_MODIFIED.getId());
                DiscrepancyNoteBean childNote = createChildNote(existingNote);
                dnDAO.create(childNote);
                dnDAO.createMapping(childNote);
                dnDAO.update(existingNote);
            }
        }
    }

    private DiscrepancyNoteBean createChildNote(DiscrepancyNoteBean parent) {
        DiscrepancyNoteBean child = new DiscrepancyNoteBean();
        child.setParentDnId(parent.getId());
        child.setDiscrepancyNoteTypeId(parent.getDiscrepancyNoteTypeId());
        child.setDetailedNotes(resword.getString("closed_modified_message"));
        child.setResolutionStatusId(parent.getResolutionStatusId());
        child.setAssignedUserId(parent.getAssignedUserId());
        child.setResStatus(parent.getResStatus());
        child.setOwner(ub);
        child.setStudyId(currentStudy.getId());
        child.setEntityId(parent.getEntityId());
        child.setEntityType(parent.getEntityType());
        child.setColumn(parent.getColumn());
        child.setField(parent.getField());

        return child;
    }

    private List<RuleSetBean> createRuleSet(StudySubjectBean ssub, StudyEventDefinitionBean sed) {

        return getRuleSetDao().findAllByStudyEventDef(sed);

    }

    private RuleSetDao getRuleSetDao() {
        return (RuleSetDao) SpringServletAccess.getApplicationContext(context).getBean("ruleSetDao");

    }

    private ArrayList getUncompletedCRFs(ArrayList eventDefinitionCRFs, ArrayList eventCRFs) {
        int i;
        HashMap completed = new HashMap();
        HashMap startedButIncompleted = new HashMap();
        ArrayList answer = new ArrayList();

        /**
         * A somewhat non-standard algorithm is used here: let answer = empty;
         * foreach event definition ED, set isCompleted(ED) = false foreach
         * event crf EC, set isCompleted(EC.getEventDefinition()) = true foreach
         * event definition ED, if (!isCompleted(ED)) { answer += ED; } return
         * answer; This algorithm is guaranteed to find all the event
         * definitions for which no event CRF exists.
         *
         * The motivation for using this algorithm is reducing the number of
         * database hits.
         *
         * -jun-we have to add more CRFs here: the event CRF which dones't have
         * item data yet
         */

        for (i = 0; i < eventDefinitionCRFs.size(); i++) {
            EventDefinitionCRFBean edcrf = (EventDefinitionCRFBean) eventDefinitionCRFs.get(i);
            completed.put(new Integer(edcrf.getCrfId()), Boolean.FALSE);
            startedButIncompleted.put(new Integer(edcrf.getCrfId()), new EventCRFBean());
        }

        CRFVersionDAO cvdao = new CRFVersionDAO(sm.getDataSource());
        ItemDataDAO iddao = new ItemDataDAO(sm.getDataSource());
        for (i = 0; i < eventCRFs.size(); i++) {
            EventCRFBean ecrf = (EventCRFBean) eventCRFs.get(i);
            int crfId = cvdao.getCRFIdFromCRFVersionId(ecrf.getCRFVersionId());
            ArrayList idata = iddao.findAllByEventCRFId(ecrf.getId());
            if (!idata.isEmpty()) {// this crf has data already
                completed.put(new Integer(crfId), Boolean.TRUE);
            } else {// event crf got created, but no data entered
                startedButIncompleted.put(new Integer(crfId), ecrf);
            }
        }

        for (i = 0; i < eventDefinitionCRFs.size(); i++) {
            DisplayEventDefinitionCRFBean dedc = new DisplayEventDefinitionCRFBean();
            EventDefinitionCRFBean edcrf = (EventDefinitionCRFBean) eventDefinitionCRFs.get(i);
            dedc.setEdc(edcrf);
            Boolean b = (Boolean) completed.get(new Integer(edcrf.getCrfId()));
            EventCRFBean ev = (EventCRFBean) startedButIncompleted.get(new Integer(edcrf.getCrfId()));
            if (b == null || !b.booleanValue()) {
                dedc.setEventCRF(ev);
                answer.add(dedc);
            }
        }

        return answer;
    }

    private void populateUncompletedCRFsWithCRFAndVersions(ArrayList uncompletedEventDefinitionCRFs) {
        CRFDAO cdao = new CRFDAO(sm.getDataSource());
        CRFVersionDAO cvdao = new CRFVersionDAO(sm.getDataSource());

        int size = uncompletedEventDefinitionCRFs.size();
        for (int i = 0; i < size; i++) {
            DisplayEventDefinitionCRFBean dedcrf = (DisplayEventDefinitionCRFBean) uncompletedEventDefinitionCRFs
                    .get(i);
            CRFBean cb = (CRFBean) cdao.findByPK(dedcrf.getEdc().getCrfId());
            // note that we do not check status in the above query, so let's
            // check it here, tbh 102007
            if (cb.getStatus().equals(Status.AVAILABLE)) {
                // the above does not allow us to show the CRF as a thing with
                // status of 'invalid' so we have to
                // go to the JSP for this one, I think
                dedcrf.getEdc().setCrf(cb);

                ArrayList versions = (ArrayList) cvdao.findAllActiveByCRF(dedcrf.getEdc().getCrfId());
                dedcrf.getEdc().setVersions(versions);
                // added tbh 092007, fix for 1461
                if (versions != null && versions.size() != 0) {
                    boolean isLocked = false;
                    for (int ii = 0; ii < versions.size(); ii++) {
                        CRFVersionBean crfvb = (CRFVersionBean) versions.get(ii);
                        logger.debug("...checking versions..." + crfvb.getName());
                        if (!crfvb.getStatus().equals(Status.AVAILABLE)) {
                            logger.debug("found a non active crf version");
                            isLocked = true;
                        }
                    }
                    logger.debug("re-set event def, line 240: " + isLocked);
                    if (isLocked) {
                        dedcrf.setStatus(Status.LOCKED);
                        dedcrf.getEventCRF().setStage(DataEntryStage.LOCKED);
                    }
                    uncompletedEventDefinitionCRFs.set(i, dedcrf);
                } else {// above added 092007, tbh
                    dedcrf.setStatus(Status.LOCKED);
                    dedcrf.getEventCRF().setStage(DataEntryStage.LOCKED);
                    uncompletedEventDefinitionCRFs.set(i, dedcrf);
                } // added 102007, tbh
            } else {
                dedcrf.getEdc().setCrf(cb);
                logger.debug("_found a non active crf _");
                dedcrf.setStatus(Status.LOCKED);
                dedcrf.getEventCRF().setStage(DataEntryStage.LOCKED);
                dedcrf.getEdc().getCrf().setStatus(Status.LOCKED);
                uncompletedEventDefinitionCRFs.set(i, dedcrf);
            } // enclosing if statement added 102007, tbh
        }
    }

    @Override
    protected String getAdminServlet() {
        if (ub.isSysAdmin()) {
            return SecureController.ADMIN_SERVLET_CODE;
        } else {
            return "";
        }
    }

    private void setRequestAttributesForNotes(List<DiscrepancyNoteBean> discBeans) {
        for (DiscrepancyNoteBean discrepancyNoteBean : discBeans) {
            if ("location".equalsIgnoreCase(discrepancyNoteBean.getColumn())) {
                request.setAttribute(HAS_LOCATION_NOTE, "yes");
                request.setAttribute(LOCATION_NOTE, discrepancyNoteBean);
            } else if ("start_date".equalsIgnoreCase(discrepancyNoteBean.getColumn())) {
                request.setAttribute(HAS_START_DATE_NOTE, "yes");
                request.setAttribute(START_DATE_NOTE, discrepancyNoteBean);
            } else if ("end_date".equalsIgnoreCase(discrepancyNoteBean.getColumn())) {
                request.setAttribute(HAS_END_DATE_NOTE, "yes");
                request.setAttribute(END_DATE_NOTE, discrepancyNoteBean);
            }

        }

    }

    private RuleSetService getRuleSetService() {
        return (RuleSetService) SpringServletAccess.getApplicationContext(context).getBean("ruleSetService");
    }

}