<commit_before>package gov.nih.nci.cabig.caaers.api.impl;

import gov.nih.nci.cabig.caaers.CaaersSystemException;
import gov.nih.nci.cabig.caaers.api.AbstractImportService;
import gov.nih.nci.cabig.caaers.api.ProcessingOutcome;
import gov.nih.nci.cabig.caaers.dao.AdverseEventDao;
import gov.nih.nci.cabig.caaers.dao.AdverseEventReportingPeriodDao;
import gov.nih.nci.cabig.caaers.dao.CtcTermDao;
import gov.nih.nci.cabig.caaers.dao.ExternalAdverseEventDao;
import gov.nih.nci.cabig.caaers.dao.ExternalAdverseEventReportingPeriodDao;
import gov.nih.nci.cabig.caaers.dao.ParticipantDao;
import gov.nih.nci.cabig.caaers.dao.StudyDao;
import gov.nih.nci.cabig.caaers.dao.StudyParticipantAssignmentDao;
import gov.nih.nci.cabig.caaers.dao.TreatmentAssignmentDao;
import gov.nih.nci.cabig.caaers.dao.index.AdverseEventIndexDao;
import gov.nih.nci.cabig.caaers.dao.query.ParticipantQuery;
import gov.nih.nci.cabig.caaers.domain.AdverseEvent;
import gov.nih.nci.cabig.caaers.domain.AdverseEventCtcTerm;
import gov.nih.nci.cabig.caaers.domain.AdverseEventMeddraLowLevelTerm;
import gov.nih.nci.cabig.caaers.domain.AdverseEventReportingPeriod;
import gov.nih.nci.cabig.caaers.domain.AeTerminology;
import gov.nih.nci.cabig.caaers.domain.Ctc;
import gov.nih.nci.cabig.caaers.domain.Epoch;
import gov.nih.nci.cabig.caaers.domain.ExpeditedAdverseEventReport;
import gov.nih.nci.cabig.caaers.domain.ExternalAEReviewStatus;
import gov.nih.nci.cabig.caaers.domain.ExternalAdverseEvent;
import gov.nih.nci.cabig.caaers.domain.ExternalAdverseEventReportingPeriod;
import gov.nih.nci.cabig.caaers.domain.Identifier;
import gov.nih.nci.cabig.caaers.domain.Participant;
import gov.nih.nci.cabig.caaers.domain.Study;
import gov.nih.nci.cabig.caaers.domain.StudyParticipantAssignment;
import gov.nih.nci.cabig.caaers.domain.StudyPersonnel;
import gov.nih.nci.cabig.caaers.domain.TreatmentAssignment;
import gov.nih.nci.cabig.caaers.domain.ajax.StudySearchableAjaxableDomainObject;
import gov.nih.nci.cabig.caaers.domain.repository.AdverseEventRoutingAndReviewRepository;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventMeddraLowLevelTermType;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventType;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEvents;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventsInputMessage;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.Criteria;
import gov.nih.nci.cabig.caaers.integration.schema.common.CaaersServiceResponse;
import gov.nih.nci.cabig.caaers.rules.business.service.AdverseEventEvaluationService;
import gov.nih.nci.cabig.caaers.security.SecurityUtils;
import gov.nih.nci.cabig.caaers.service.AdverseEventReportingPeriodService;
import gov.nih.nci.cabig.caaers.service.migrator.adverseevent.AdverseEventConverter;
import gov.nih.nci.cabig.caaers.tools.configuration.Configuration;
import gov.nih.nci.cabig.caaers.utils.DateUtils;
import gov.nih.nci.cabig.caaers.validation.AdverseEventGroup;
import gov.nih.nci.cabig.caaers.validation.ValidationError;
import gov.nih.nci.cabig.caaers.validation.ValidationErrors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

import com.semanticbits.rules.impl.BusinessRulesExecutionServiceImpl;
import org.springframework.transaction.annotation.Transactional;

public class AdverseEventManagementServiceImpl extends AbstractImportService implements ApplicationContextAware {

	public static final String CREATE = "create";
	public static final String UPDATE = "update";
	public static final String DELETE = "delete";
	
	private Validator validator;

	protected BusinessRulesExecutionServiceImpl executionService;
	protected AdverseEventDao adverseEventDao;
	protected ParticipantDao participantDao;
	protected StudyDao studyDao;
	protected StudyParticipantAssignmentDao studyParticipantAssignmentDao;
	protected AdverseEventIndexDao adverseEventIndexDao;
	protected AdverseEventReportingPeriodDao adverseEventReportingPeriodDao;
	protected ExternalAdverseEventReportingPeriodDao externalAdverseEventReportingPeriodDao;
	protected ExternalAdverseEventDao externalAdverseEventDao;

	protected TreatmentAssignmentDao treatmentAssignmentDao;
	protected CtcTermDao ctcTermDao;

	private AdverseEventConverter adverseEventConverter;
	private AdverseEventEvaluationService adverseEventEvaluationService;
	private AdverseEventReportingPeriodService adverseEventReportingPeriodService;
	private MailSender mailSender;
	private ApplicationContext applicationContext;
	private MessageSource messageSource;
    private Configuration configuration;
    private AdverseEventRoutingAndReviewRepository adverseEventRoutingAndReviewRepository;

	private static Log logger = LogFactory.getLog(AdverseEventManagementServiceImpl.class);

	public CaaersServiceResponse deleteAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		CaaersServiceResponse response = Helper.createResponse();
		if (adverseEventsInputMessage.getAdverseEvents() == null) {
			return Helper.populateError(response, "WS_AEMS_026", messageSource.getMessage("WS_AEMS_026",
					new String[] {}, "", Locale.getDefault()));
		}
		return saveAdverseEvent(adverseEventsInputMessage, DELETE);
	}

	public CaaersServiceResponse createOrUpdateAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		return saveAdverseEvent(adverseEventsInputMessage, UPDATE);
	}

	public CaaersServiceResponse createAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		return saveAdverseEvent(adverseEventsInputMessage, CREATE);
	}
	
	private boolean validateAdverseEventInputMessage(AdverseEventsInputMessage adverseEventsInputMessage, CaaersServiceResponse caaersServiceResponse){
		
		Boolean validMessage = true;
		if (adverseEventsInputMessage.getAdverseEvents() == null) {
			Helper.populateError(caaersServiceResponse, "WS_AEMS_025",
                    messageSource.getMessage( "WS_AEMS_025", new String[] {}, "", Locale.getDefault())
            );
			validMessage = false;
		}
		
		if (adverseEventsInputMessage.getCriteria().getCourse() == null) {
            Helper.populateError(caaersServiceResponse, "WS_AEMS_065",
                    messageSource.getMessage("WS_AEMS_065", new String[] { }, "", Locale.getDefault())
            );
            validMessage = false;
		}
		
		return validMessage;
	}

    public boolean isWorkflowEnabled(){
        return configuration.get(Configuration.ENABLE_WORKFLOW);
    }
	
	/**
	 * @param criteria
	 * @param assignment
	 * @param caaersServiceResponse
	 * @return AdverseEventReportingPeriod
	 */
	private AdverseEventReportingPeriod fetchAEReportingPeriod(Criteria criteria,
			StudyParticipantAssignment assignment, CaaersServiceResponse caaersServiceResponse, String externalId) {
		AdverseEventReportingPeriod adverseEventReportingPeriod = null;
		if (criteria.getCourse() != null) {
			try {
				adverseEventReportingPeriod = createDomainReportingPeriodIfNotExists(criteria, assignment, externalId);
			} catch (CaaersSystemException e) {
				logger.error(e);
				Helper.populateError(caaersServiceResponse, e.getErrorCode(), e.getMessage());
			}
		}
		return adverseEventReportingPeriod;
	}
	
	private AdverseEventReportingPeriod createDomainReportingPeriodIfNotExists(Criteria criteria, StudyParticipantAssignment assignment, String externalId) throws CaaersSystemException {
		List<AdverseEventReportingPeriod> rPeriodList = adverseEventReportingPeriodDao.getByAssignment(assignment);
		
		String treatmentAssignmentCode = null;
		String otherTreatmentAssignmentDescription = null; 
		if((treatmentAssignmentCode = criteria.getCourse().getTreatmentAssignmentCode()) != null){
			for (AdverseEventReportingPeriod matchingDomainAdverseEventReportingPeriod : rPeriodList) {
				// compare TAC and treatment type to determine if matchingDomainAdverseEventReportingPeriod exists.
				if(matchingDomainAdverseEventReportingPeriod.getTreatmentAssignment().getCode() != null && matchingDomainAdverseEventReportingPeriod.
						getTreatmentAssignment().getCode().equals(treatmentAssignmentCode) && criteria.getCourse().getTreatmentType().
						equals(matchingDomainAdverseEventReportingPeriod.getEpoch().getName())){
					return matchingDomainAdverseEventReportingPeriod;
				}
			}
		} else if ((otherTreatmentAssignmentDescription = criteria.getCourse().getOtherTreatmentAssignmentDescription()) != null){<commit_msg>CAAERS-5860:Implement saving provisional adverse event reporting period and adverse events from Force.com -NPE fix<commit_after>package gov.nih.nci.cabig.caaers.api.impl;

import gov.nih.nci.cabig.caaers.CaaersSystemException;
import gov.nih.nci.cabig.caaers.api.AbstractImportService;
import gov.nih.nci.cabig.caaers.api.ProcessingOutcome;
import gov.nih.nci.cabig.caaers.dao.AdverseEventDao;
import gov.nih.nci.cabig.caaers.dao.AdverseEventReportingPeriodDao;
import gov.nih.nci.cabig.caaers.dao.CtcTermDao;
import gov.nih.nci.cabig.caaers.dao.ExternalAdverseEventDao;
import gov.nih.nci.cabig.caaers.dao.ExternalAdverseEventReportingPeriodDao;
import gov.nih.nci.cabig.caaers.dao.ParticipantDao;
import gov.nih.nci.cabig.caaers.dao.StudyDao;
import gov.nih.nci.cabig.caaers.dao.StudyParticipantAssignmentDao;
import gov.nih.nci.cabig.caaers.dao.TreatmentAssignmentDao;
import gov.nih.nci.cabig.caaers.dao.index.AdverseEventIndexDao;
import gov.nih.nci.cabig.caaers.dao.query.ParticipantQuery;
import gov.nih.nci.cabig.caaers.domain.AdverseEvent;
import gov.nih.nci.cabig.caaers.domain.AdverseEventCtcTerm;
import gov.nih.nci.cabig.caaers.domain.AdverseEventMeddraLowLevelTerm;
import gov.nih.nci.cabig.caaers.domain.AdverseEventReportingPeriod;
import gov.nih.nci.cabig.caaers.domain.AeTerminology;
import gov.nih.nci.cabig.caaers.domain.Ctc;
import gov.nih.nci.cabig.caaers.domain.Epoch;
import gov.nih.nci.cabig.caaers.domain.ExpeditedAdverseEventReport;
import gov.nih.nci.cabig.caaers.domain.ExternalAEReviewStatus;
import gov.nih.nci.cabig.caaers.domain.ExternalAdverseEvent;
import gov.nih.nci.cabig.caaers.domain.ExternalAdverseEventReportingPeriod;
import gov.nih.nci.cabig.caaers.domain.Identifier;
import gov.nih.nci.cabig.caaers.domain.Participant;
import gov.nih.nci.cabig.caaers.domain.Study;
import gov.nih.nci.cabig.caaers.domain.StudyParticipantAssignment;
import gov.nih.nci.cabig.caaers.domain.StudyPersonnel;
import gov.nih.nci.cabig.caaers.domain.TreatmentAssignment;
import gov.nih.nci.cabig.caaers.domain.ajax.StudySearchableAjaxableDomainObject;
import gov.nih.nci.cabig.caaers.domain.repository.AdverseEventRoutingAndReviewRepository;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventMeddraLowLevelTermType;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventType;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEvents;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.AdverseEventsInputMessage;
import gov.nih.nci.cabig.caaers.integration.schema.adverseevent.Criteria;
import gov.nih.nci.cabig.caaers.integration.schema.common.CaaersServiceResponse;
import gov.nih.nci.cabig.caaers.rules.business.service.AdverseEventEvaluationService;
import gov.nih.nci.cabig.caaers.security.SecurityUtils;
import gov.nih.nci.cabig.caaers.service.AdverseEventReportingPeriodService;
import gov.nih.nci.cabig.caaers.service.migrator.adverseevent.AdverseEventConverter;
import gov.nih.nci.cabig.caaers.tools.configuration.Configuration;
import gov.nih.nci.cabig.caaers.utils.DateUtils;
import gov.nih.nci.cabig.caaers.validation.AdverseEventGroup;
import gov.nih.nci.cabig.caaers.validation.ValidationError;
import gov.nih.nci.cabig.caaers.validation.ValidationErrors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

import com.semanticbits.rules.impl.BusinessRulesExecutionServiceImpl;
import org.springframework.transaction.annotation.Transactional;

public class AdverseEventManagementServiceImpl extends AbstractImportService implements ApplicationContextAware {

	public static final String CREATE = "create";
	public static final String UPDATE = "update";
	public static final String DELETE = "delete";
	
	private Validator validator;

	protected BusinessRulesExecutionServiceImpl executionService;
	protected AdverseEventDao adverseEventDao;
	protected ParticipantDao participantDao;
	protected StudyDao studyDao;
	protected StudyParticipantAssignmentDao studyParticipantAssignmentDao;
	protected AdverseEventIndexDao adverseEventIndexDao;
	protected AdverseEventReportingPeriodDao adverseEventReportingPeriodDao;
	protected ExternalAdverseEventReportingPeriodDao externalAdverseEventReportingPeriodDao;
	protected ExternalAdverseEventDao externalAdverseEventDao;

	protected TreatmentAssignmentDao treatmentAssignmentDao;
	protected CtcTermDao ctcTermDao;

	private AdverseEventConverter adverseEventConverter;
	private AdverseEventEvaluationService adverseEventEvaluationService;
	private AdverseEventReportingPeriodService adverseEventReportingPeriodService;
	private MailSender mailSender;
	private ApplicationContext applicationContext;
	private MessageSource messageSource;
    private Configuration configuration;
    private AdverseEventRoutingAndReviewRepository adverseEventRoutingAndReviewRepository;

	private static Log logger = LogFactory.getLog(AdverseEventManagementServiceImpl.class);

	public CaaersServiceResponse deleteAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		CaaersServiceResponse response = Helper.createResponse();
		if (adverseEventsInputMessage.getAdverseEvents() == null) {
			return Helper.populateError(response, "WS_AEMS_026", messageSource.getMessage("WS_AEMS_026",
					new String[] {}, "", Locale.getDefault()));
		}
		return saveAdverseEvent(adverseEventsInputMessage, DELETE);
	}

	public CaaersServiceResponse createOrUpdateAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		return saveAdverseEvent(adverseEventsInputMessage, UPDATE);
	}

	public CaaersServiceResponse createAdverseEvent(AdverseEventsInputMessage adverseEventsInputMessage) {
		return saveAdverseEvent(adverseEventsInputMessage, CREATE);
	}
	
	private boolean validateAdverseEventInputMessage(AdverseEventsInputMessage adverseEventsInputMessage, CaaersServiceResponse caaersServiceResponse){
		
		Boolean validMessage = true;
		if (adverseEventsInputMessage.getAdverseEvents() == null) {
			Helper.populateError(caaersServiceResponse, "WS_AEMS_025",
                    messageSource.getMessage( "WS_AEMS_025", new String[] {}, "", Locale.getDefault())
            );
			validMessage = false;
		}
		
		if (adverseEventsInputMessage.getCriteria().getCourse() == null) {
            Helper.populateError(caaersServiceResponse, "WS_AEMS_065",
                    messageSource.getMessage("WS_AEMS_065", new String[] { }, "", Locale.getDefault())
            );
            validMessage = false;
		}
		
		return validMessage;
	}

    public boolean isWorkflowEnabled(){
        return configuration.get(Configuration.ENABLE_WORKFLOW);
    }
	
	/**
	 * @param criteria
	 * @param assignment
	 * @param caaersServiceResponse
	 * @return AdverseEventReportingPeriod
	 */
	private AdverseEventReportingPeriod fetchAEReportingPeriod(Criteria criteria,
			StudyParticipantAssignment assignment, CaaersServiceResponse caaersServiceResponse, String externalId) {
		AdverseEventReportingPeriod adverseEventReportingPeriod = null;
		if (criteria.getCourse() != null) {
			try {
				adverseEventReportingPeriod = createDomainReportingPeriodIfNotExists(criteria, assignment, externalId);
			} catch (CaaersSystemException e) {
				logger.error(e);
				Helper.populateError(caaersServiceResponse, e.getErrorCode(), e.getMessage());
			}
		}
		return adverseEventReportingPeriod;
	}
	
	private AdverseEventReportingPeriod createDomainReportingPeriodIfNotExists(Criteria criteria, StudyParticipantAssignment assignment, String externalId) throws CaaersSystemException {
		List<AdverseEventReportingPeriod> rPeriodList = adverseEventReportingPeriodDao.getByAssignment(assignment);
		
		String treatmentAssignmentCode = null;
		String otherTreatmentAssignmentDescription = null; 
		if((treatmentAssignmentCode = criteria.getCourse().getTreatmentAssignmentCode()) != null){
			for (AdverseEventReportingPeriod matchingDomainAdverseEventReportingPeriod : rPeriodList) {
				// compare TAC and treatment type to determine if matchingDomainAdverseEventReportingPeriod exists.
				if(matchingDomainAdverseEventReportingPeriod.getTreatmentAssignment().getCode() != null && matchingDomainAdverseEventReportingPeriod.
						getTreatmentAssignment().getCode().equals(treatmentAssignmentCode) && criteria.getCourse().getTreatmentType() == null ? 
								true:criteria.getCourse().getTreatmentType().equals(matchingDomainAdverseEventReportingPeriod.getEpoch().getName())){
					return matchingDomainAdverseEventReportingPeriod;
				}
			}
		} else if ((otherTreatmentAssignmentDescription = criteria.getCourse().getOtherTreatmentAssignmentDescription()) != null){
{'fraction_non_alphanumeric': 0.08742759064578416, 'fraction_numerical': 0.002145462347135808, 'mean_word_length': 6.69500619067272, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '836505', 'n_tokens_mistral': 6029, 'n_tokens_neox': 5781, 'n_words': 809}