
/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.service.impl;

// Java classes
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.Validate;


import gov.va.med.fw.cache.TriggerEventCacheManager;
import gov.va.med.fw.model.AbstractEntity;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.service.ServiceException;

import gov.va.med.esr.UseCaseName;
import gov.va.med.esr.common.batchprocess.LoadVSSCDataResult;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.ee.SHAD;
import gov.va.med.esr.common.model.lookup.CampLejeuneChangeSource;
import gov.va.med.esr.common.model.lookup.DischargeType;
import gov.va.med.esr.common.model.lookup.EligibilityVerificationSource;
import gov.va.med.esr.common.model.lookup.FunctionalGroup;
import gov.va.med.esr.common.model.lookup.Indicator;
import gov.va.med.esr.common.model.lookup.RegistryType;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.lookup.WkfCaseType;

import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.ee.CampLejeuneVerification;
import gov.va.med.esr.common.model.ee.MilitaryServiceEpisode;
import gov.va.med.esr.common.model.ee.MilitaryServiceSiteRecord;
import gov.va.med.esr.common.model.ee.PurpleHeart;
import gov.va.med.esr.common.model.ee.MilitaryService;
import gov.va.med.esr.common.model.lookup.MilitaryServiceQueryStatus;
import gov.va.med.esr.service.EligibilityEnrollmentService;
import gov.va.med.esr.service.MessagingService;
import gov.va.med.esr.service.MilitaryInfoService;
import gov.va.med.esr.service.MsdsResponseInfo;
import gov.va.med.esr.service.PersonService;
import gov.va.med.esr.service.RegistryService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.esr.service.WorkflowService;
//import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.esr.common.rule.service.EventRuleService;
import gov.va.med.esr.common.rule.service.MergeRuleService;
import gov.va.med.esr.common.rule.service.MilitaryRuleService;
import gov.va.med.esr.common.util.CommonDateUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * Provides business methods to support use cases for update a veteran military service information </br> </br> <b>Project:</b> Common </br>
 *
 * @author DNS   LEV
 * @version 1.0
 */
public class MilitaryInfoServiceImpl extends AbstractHistoricalInfoServiceImpl implements MilitaryInfoService
{
	public static final String PUNCTUATION_CHARS = "[,.'`]";
    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = -76551275928447239L;

	private static final ImpreciseDate startday = new ImpreciseDate("19530801");
	private static final ImpreciseDate endday = new ImpreciseDate("19871231");

    /**
     * An instance of eligibilityEnrollmentService
     */
    private EligibilityEnrollmentService eligibilityEnrollmentService = null;

    /**
     * An instance of registryService.
     */

    private RegistryService registryService = null;

    private WorkflowService workflowService = null;

    /**
     * An instance of triggerEventCacheManager
     */
    private TriggerEventCacheManager triggerEventCacheManager;

    private MessagingService messagingService = null;

    /**
     * A default constructor
     */
    public MilitaryInfoServiceImpl()
    {
        super();
    }

    /**
     * @see gov.va.med.esr.service.MilitaryInfoService#getHistoricalMilitaryServiceBySite(gov.va.med.fw.model.EntityKey)
     */
    public Set getHistoricalMilitaryServiceBySite(EntityKey key) throws ServiceException
    {
        // FIXME Auto-generated method stub
        return null;
    }

    public WorkflowService getWorkflowService() {
		return workflowService;
	}

	public void setWorkflowService(WorkflowService workflowService) {
		this.workflowService = workflowService;
	}

    /**
     * This method implements the following use cases <br> </br> <b>2219 [UC23.1]</b> This use case describes how the actor adds or modifies </br> military service information and views historical
     * military service information </br> </br> <b>3171 [UC23.4]</b> Update Military Service Information </br> The actor is allowed to update the following Military Service Information. </br> Specific
     * Requirements are found in the Special Requirements Section: </br> </br> <li> Branch of Service <li> Service Entry Date <li> Service Separation Date <li> Service Discharge Type <li> Military
     * Service Number <li> Filipino Veteran Proof <li> Conflict Location(s) <li> Conflict From Date <li> Conflict To Date <li> Military Disability Retirement <li> Discharge Due to Disability <li>
     * Radiation Exposure Indicator <li> Radiation Exposure Method <li> Agent Orange Indicator <li> Agent Orange Exposure Location <li> Environmental Contaminants Indicator <li> HEC Period Of Service
     * (POS) <li> SHAD Indicator </br> </br> <b>3172 [UC23.5]</b> Determine Eligibility </br> <b>4354 [UC23.6]</b> Trigger Letter/Email Bulletin </br> <b>4355 [UC23.7]</b> Send Update Message (Z11)
     * </br> </br>
     *
     * @param incoming An incoming veteran whose military service is to be updated
     *
     * @return Person A veteran with updated information
     * @throws ServiceException Thrown in case of error updating a veteran's military info
     */
    public Person updateMilitaryServiceInformation(Person incoming) throws ServiceException
    {

        Validate.notNull(incoming, "An person to be updated must not be null ");

        // Get the current person on file
        PersonService personService = this.getPersonService();
        Person onFile = personService.getPerson((PersonEntityKey)incoming.getEntityKey());
        //CCR12710
        if (logger.isDebugEnabled()) {
	          logger.debug("MilInfoServiceImpl updateSvcInfo : person: " + incoming);
	    }

        // Ensure that something changed on the incoming entity as compared to the onFile entity
        ensureEntityChanged(incoming, onFile);

        // Validate that an enrollment record exists for the on-file Person
        validateEnrollmentDetermination(onFile);

        // Merge the special factors
        this.getEligibilityFactorRuleService().manageSpecialFactors(incoming, onFile);

        // Step 1: Get a military rule service to manage the update of a military service
        Person updated = this.getMilitaryRuleService().manageMilitaryService(incoming.getMilitaryService(), onFile);

        // Step 2: Get an enrollment service to determine eligibility. Letters and e-mail
        // will be triggered in this step
        updated = this.getEligibilityEnrollmentService().assessEEImpact(updated, false);

        // save dental information
        updated.setEligibleForClassIIDental(incoming.getEligibleForClassIIDental());
        if (incoming.getEligibleForClassIIDental()!=null && Boolean.FALSE.equals(incoming.getEligibleForClassIIDental()))
        {
        	updated.setClassIIDentalApplicationDueBefore(null);
        }

        // Step 3: Send update Z11
        this.getEventRuleService().manageMessageEvents(onFile);
        //Step 4: Link Shad registry.
        SHAD incomingShad=incoming.getShad();
        if(incomingShad!=null && onFile!=null && incomingShad.getRegistryTrait()==null)
        {
        	RegistryType regType=(RegistryType)this.getLookupService().getByCode(RegistryType.class,RegistryType.CODE_SHAD_REGISTRY.getCode());
        	this.getRegistryService().linkPersonRegistry(incomingShad, onFile.getShad(), incoming, onFile, regType, true);
        }
        //hanbook
        EventRuleService eventRuleService = this.getEventRuleService();
        eventRuleService.manageHandBookEvents(updated);
        // Step 5: Save
        return personService.save(updated);
    }


    /**
     * @see gov.va.med.esr.service.MilitaryInfoService#calculatePeriodOfService(gov.va.med.esr.common.model.person.Person)
     */
    public Person updateCalculatePeriodOfService(Person incoming) throws ServiceException
    {
        Validate.notNull(incoming, "An person to be calculated must not be null ");

        // Get the current person on file
        PersonService personService = this.getPersonService();
        Person onFile = personService.getPerson((PersonEntityKey)incoming.getEntityKey());

        // Step 1: Calculates a period of service for an incoming person. Pass only cloned person because onFile person is a
        // persistant object and this method is in a transaction, the changes to onFile will get persisted.
        //CCR12710
        if (logger.isDebugEnabled()) {
	          logger.debug("MilInfoServiceImpl caclPdOfSvc : person: " + incoming);
	    }
        this.getMilitaryRuleService().calculatePeriodOfServiceForUI(incoming, (Person)onFile.clone(),UseCaseName.MS);

        // This method is only called by a UI component so return an incoming person here
        // An incoming person contains updated period of services.
        return incoming;
    }

    /**
     * Process VSSC data for oef/oif episodes
     */
    public LoadVSSCDataResult processVSSCData(Person incoming) throws ServiceException
    {
    	Validate.notNull(incoming, "Person must not be null ");
    	LoadVSSCDataResult result = new LoadVSSCDataResult();

        //CCR 11403: for Vista inbound messages, check 200ESR Correlation, add 200ESRCorreltion if necessary
        this.getPersonService().checkAndAddESRCorrelation(incoming);

        //Check for eligibility record
        if (incoming.getEnrollmentDetermination() == null){
        	//New Person no eligibility record - can not be updated
        	result.incrementCountNewPersonRejected(incoming.getMilitaryService().getCombatEpisodes().size());
        	return result;
        }
        // Get the current person on file
        //Call rules service to merge records and update
        Person onFile = this.getPersonService().getPerson((PersonEntityKey)incoming.getEntityKey());

        // Step 1: Get a military rule service to manage the update of a military service
        Person updated =
        	this.getMilitaryRuleService().processVSSCData(incoming.getMilitaryService(), onFile, result);

        // Step 2: Get an enrollment service to determine eligibility. Letters and e-mail
        // will be triggered in this step
        updated = this.getEligibilityEnrollmentService().assessEEImpact(updated, false);

        // Step 3: Send update Z11
        this.getEventRuleService().manageMessageEvents(onFile);
        this.getEventRuleService().manageHandBookEvents(onFile);

        // Step 4: Save
        this.getPersonService().save(updated);

        //Result is updated in the rules

        return result;
    }


    /**
     * Test Method for Junit to process a person from ESR through the MSDS rules
     *
     * @param person
     */
	public Person processMSDSData(Person incoming) throws ServiceException {

		MsdsResponseInfo info = new MsdsResponseInfo();
		info.setEsrPerson(incoming);
		return processMSDSData(info);
	}

	/**
	 * Production Entry point for processing contents of MSDS Message
	 *
	 * @see gov.va.med.esr.service.MilitaryInfoService#processMSDSData(gov.va.med.esr.service.MsdsResponseInfo)
	 */
	public Person processMSDSData(MsdsResponseInfo response) throws ServiceException {
		if (logger.isDebugEnabled()) {
		        	logger.debug("MilitaryInfoServiceImpl processMSDSData : response: " + ToStringBuilder.reflectionToString(response, ToStringStyle.MULTI_LINE_STYLE) );
	    }

		Validate.notNull(response, "The MSDS response info must not be null ");
		Person incoming = null;
		// Get the current person on file
		PersonService personService = this.getPersonService();
		Person onFile = null;
		if (response.getEsrPerson() != null) {
			incoming = response.getEsrPerson();
			onFile = personService.getPerson(incoming.getPersonEntityKey());
		}
		else {
			onFile = personService.getPerson(response.getPersonEntityKey());
			Validate.notNull(onFile, "A person to be updated must not be null ");
			incoming = (Person)onFile.clone(); // make a copy
		}

		Validate.notNull(incoming, "An incoming person must not be null ");
		Validate.notNull(onFile, "A person to be updated must not be null ");

		// Ensure that something changed on the incoming entity as compared to the onFile entity
		//ensureEntityChanged(incoming, onFile);

		// Get a military rule service to process the MSDS data
		Person tempOnFile = (Person)onFile.clone();
		boolean terminate = this.getMilitaryRuleService().processMSDSData(incoming, tempOnFile, response);

		triggerEventCacheManager.removeTriggerEvents();

		if (!terminate) {

			// Get an enrollment service to determine eligibility. Letters and e-mail
			// will be triggered in this step
			this.getEligibilityEnrollmentService().assessEEImpact(tempOnFile, true);

			// Provide the incoming & merged result. The rules will obtain pristine for comparison.
			boolean improved = this.getMilitaryRuleService().evaluateMSDSImprovement(incoming, tempOnFile, response);

			if (improved) {
				// this step processes the person connected to session
				boolean isError = this.getMilitaryRuleService().processMSDSData(incoming, onFile, response);

				this.getEligibilityEnrollmentService().assessEEImpact(onFile, true);

				if (isError == false) {
					//if (logger.isDebugEnabled()) {
					//	logger.debug("MilitaryInfoServiceImpl processMSDSData : isError: " + isError + " onFile: " + ToStringBuilder.reflectionToString(onFile, ToStringStyle.MULTI_LINE_STYLE)  );
					//}
					onFile = this.getMilitaryRuleService().processMilitaryServiceNumbers(onFile);
					//if (logger.isDebugEnabled()) {
					//	logger.debug("MilitaryInfoServiceImpl processMSDSData : after processing onFile: " + ToStringBuilder.reflectionToString(onFile, ToStringStyle.MULTI_LINE_STYLE)  );
					//}
				}

				// Send update Z11
				this.getEventRuleService().processMessageEventsForMsds(onFile);

				this.getCommunicationRuleService().triggerAutomaticLetters(onFile, null, null);

				// Link purpleHeart registry.
				PurpleHeart resultPurpleHeart=onFile.getPurpleHeart();
				if(resultPurpleHeart!=null && resultPurpleHeart.getRegistryTrait() == null)
				{
					RegistryType regType=(RegistryType)this.getLookupService().getByCode(RegistryType.class,RegistryType.CODE_PH_REGISTRY.getCode());
					this.getRegistryService().linkPersonRegistry(resultPurpleHeart, onFile.getPurpleHeart(), incoming, onFile, regType, false);
				}
			}
			else {
				// Noticed that we were not acknowledging query response when No Upgrade
				MilitaryService ms = onFile.getMilitaryService();
				if (ms == null) {
					ms = new MilitaryService();
					onFile.setMilitaryService(ms);
				}
				onFile.getMilitaryService().setMilitaryServiceQueryStatus(
						this.getLookupService().getMilitaryServiceQueryStatusByCode(MilitaryServiceQueryStatus.MILITARY_SERVICE_DATA_RECEIVED.getCode()));
			}
		}
		else {
			// this step processes the person connected to session and updates ms query status with issue
			this.getMilitaryRuleService().processMSDSData(incoming, onFile, response);
		}


		boolean hecRecordExists = false;

		//apply reconciliation if we did not create a hec record using Vadir/Birls data
		if (onFile.getMilitaryService() != null) {
			if (onFile.getMilitaryService().getHECMilitaryServiceSiteRecord() == null ||
					onFile.getMilitaryService().getHECMilitaryServiceSiteRecord().getMilitaryServiceEpisodes().isEmpty()) {
				this.getEventRuleService().triggerCreateHecRecord(onFile);
			}
			else{
			    hecRecordExists = true;
			}
		}

		//NOTE: this method must be called after all the MSDS rules are done
		if (hecRecordExists && handleCLELogic(onFile)) {
			//re-calculate E&E
			onFile = this.getEligibilityEnrollmentService().assessEEImpact(onFile, false);
		}
		// All the process is done. now check we need to send a new Handbook
		// or handbook insert. calling handbook rule fllow.
		this.getEventRuleService().manageHandBookEvents(onFile);


    	//Save and return
		return personService.save(onFile);
	}

	public Person processSeeding(Person incoming) throws ServiceException{

		Validate.notNull(incoming, "Person must not be null ");

        Person onFile = this.getPersonService().getPerson( incoming.getPersonEntityKey() );

        Person updated =
        	this.getMilitaryRuleService().processSeedingMilitaryService(incoming.getMilitaryService(), onFile);

        return this.getPersonService().save(updated);
	}
	public void processMSDSLogicForCLV(Person incoming) throws ServiceException{

		Validate.notNull(incoming, "Person must not be null ");

        Person onFile = this.getPersonService().getPerson( incoming.getPersonEntityKey() );

      //NOTE: this method must be called after all the MSDS rules are done
		if (handleCLELogic(onFile)) {
			//re-calculate E&E
			onFile = this.getEligibilityEnrollmentService().assessEEImpact(onFile, false);
		}
	}

    /**
     * @return Returns the eligibilityEnrollmentService.
     */
    public EligibilityEnrollmentService getEligibilityEnrollmentService()
    {
        return eligibilityEnrollmentService;
    }

    /**
     * @param eligibilityEnrollmentService The eligibilityEnrollmentService to set.
     */
    public void setEligibilityEnrollmentService(
        EligibilityEnrollmentService eligibilityEnrollmentService)
    {
        this.eligibilityEnrollmentService = eligibilityEnrollmentService;
    }

    /**
     * @return Returns the registryService.
     */
    public RegistryService getRegistryService()
    {
        return registryService;
    }

    /**
     * Sets registryService.
     * @param registryService
     */
    public void setRegistryService(
    		RegistryService registryService)
    {
        this.registryService = registryService;
    }

	public TriggerEventCacheManager getTriggerEventCacheManager() {
		return triggerEventCacheManager;
	}

	public void setTriggerEventCacheManager(
			TriggerEventCacheManager triggerEventCacheManager) {
		this.triggerEventCacheManager = triggerEventCacheManager;
	}

	public MessagingService getMessagingService() {
		return messagingService;
	}

	public void setMessagingService(MessagingService messagingService) {
		this.messagingService = messagingService;
	}
	////////////CLV///////////////////////////////
	public boolean calculateCLVeligibilitybyMSE(Person person) throws ServiceException{
		Validate.notNull(person, "The Person must not be null");
		if (person.getMilitaryService() == null)
			return false;
		if(person.isVeteran()==null)
		{
			return false;
		}
		return isCLVeligibilitybyMSE(person.getMilitaryService().getMilitaryServiceSiteRecords(), person.isVeteran());

	}

    private boolean isCLVeligibilitybyMSE(Set<MilitaryServiceSiteRecord> mssrs, boolean isVeteran) throws ServiceException{
    	long totalServiceDays =0;
    	VAFacility site = null;
    	for( MilitaryServiceSiteRecord mssr : mssrs )
    	{
    		site = mssr.getSite();
			if (site== null || !site.getStationNumber().equals(VAFacility.CODE_HEC.getName()))
			{
				continue;
			}

    		Set<MilitaryServiceEpisode> mses = mssr.getMilitaryServiceEpisodes();
    		for(MilitaryServiceEpisode mse :mses)
    		{
    			if((mse.getDischargeType()!=null) &&(! mse.getDischargeType().getCode().equals(DischargeType.CODE_BAD_CONDUCT.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_OTHER_THAN_HONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE_VA.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_UNDESIRABLE.getCode())))
    			{
    				if (isVeteran)
    				{
    					if((CommonDateUtils.isDateAfter(mse.getStartDate(), startday) || startday.equals(mse.getStartDate()))
    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate()))
    					)
    					{
    						totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),mse.getEndDate());

    					}
    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), startday) || startday.equals(mse.getEndDate()) )
    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate())))
    					{
    						totalServiceDays+=CommonDateUtils.getDays(startday,mse.getEndDate());

    					}
    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), endday)||endday.equals(mse.getEndDate()))
    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
    					)
    					{
    						totalServiceDays+=CommonDateUtils.getDays(startday,endday);

    					}
    					else if(CommonDateUtils.isDateBefore(mse.getStartDate(), endday)==true || endday.equals(mse.getStartDate()))
    					{

    						if (CommonDateUtils.isDateAfter(mse.getStartDate(), startday) ==true || startday.equals(mse.getStartDate()))
    						{
    							if (CommonDateUtils.isDateAfter(mse.getEndDate(), endday) ==true || endday.equals(mse.getEndDate()))
    							{
    								totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),endday);
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	if (totalServiceDays>=30)
    		return true;
    	else
    		return false;

    }

	///////////CLV////////////////////////////////
	public boolean handleCLELogic(Person person) throws ServiceException,UnknownLookupTypeException
	{
		CampLejeuneVerification clv = person.getCampLejeuneVerification();
		if (person.getEnrollmentDetermination() != null &&
				(clv != null && clv.getSpecialFactorIndicator()!= null && clv.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode()) ) ) {
			//(clv != null && clv.getSpecialFactorIndicator()!= null && clv.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode()) && clv.getChangeSource() != null && !clv.getChangeSource().getCode().equals("4")) ) {
			//existing CLE = Yes
			if (!calculateCLVeligibilitybyMSE(person)) {
				//loss of Camp Lejeune eligibility
				if (VOAApplicationServiceImpl.VOA_IND_2.equals(person.getVOAIndicator())) {
					//CCR13810: if VOA submission, new person just added, and CLE = YES
					//check for CLE Eligibility and set the onFile CLV from Yes to No if eligibility rules fail
					//Create a workload item of type VOA with a Reason of “Veteran CL Eligibility cannot be determined”.
					//VOA_IND = 2 -> VOA NEW RECORD: for Anonymous/LOA1, it means MVI extended search not found, person was added explicitly
					this.changeCLVToNo(person); //flip from Yes to No

					//create VOA workitem
					this.createCLENotDeterminedWkItem(person,WkfCaseType.CODE_VETERANS_ONLINE_APPLICATION.getCode(), "Veteran CL Eligibility cannot be determined"); //create work item
					return true;
				} else {
				    //13880:
				    //Indicator should be flipped from YES to NO (regardless of verification method presence) when MSE data is changed
				    //and results in a loss of CL eligibility – no matter the source of change.
				    //If a verification method is present when the flag is flipped – create a worklist item.
				    //Otherwise, do NOT create a worklist item.
					this.changeCLVToNo(person); //flip from Yes to No
					if (clv.getCampLejeuneVerificationMethods().size() !=0) {
						//create eligibility updates work item
						this.createCLENotDeterminedWkItem(person,WkfCaseType.CODE_ELIGIBILITY_UPDATE.getCode(), "Camp Lejeune eligibility is not supported by MSE" ); //create work item
					}

					return true;
				}
			}
		}

		return false;
	}

	//		•	Once MSDS response is received and processed, if CL Eligibility rules fail:
	//		o	Update CLE from Yes to No.
	//		o	Update Change Site to “HEC”
	//		o	Update Source of Change to “CEV”
	private void changeCLVToNo(Person person) throws ServiceException{

		CampLejeuneVerification clv = person.getCampLejeuneVerification();

		if (clv == null)
			return;

		clv.setSpecialFactorIndicator(this.getLookupService().getIndicatorByCode(Indicator.NO));
		clv.setChangeSite(this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode()));
		clv.setChangeSource(this.getLookupService().getCampLejeuneChangeSourceByCode(CampLejeuneChangeSource.CODE_HEC.getCode())); //CEV

	}

	//Create a workload item of type VOA with a Reason of “Veteran CL Eligibility cannot be determined”.
	private void createCLENotDeterminedWkItem(Person person, String caseType, String reason) throws ServiceException{
		this.getWorkflowService().autoCreateCase(
				person,
				getLookupService().getFunctionalGroupByCode(FunctionalGroup.EE.getCode()),
				getLookupService().getWkfCaseTypeByCode(caseType),
				null,
				reason);
	}

	/**
	 * Get Service serviceEntryDate for imprecise dates to make them precise
	 * @param serviceEntryDate
	 * @return serviceEntryDate
	 *
	 * RTC Defect # 328325
	 */
	public String getPreciseServiceEntryDate(String serviceEntryDate){
		// get the imprecise service Entry dates and add 01 if day is missing or 0101 if both month and day are missing and return service Entry date.
	    if(serviceEntryDate!=null && serviceEntryDate.length()==6){
            serviceEntryDate=serviceEntryDate+"01";
	    }
        if(serviceEntryDate !=null && serviceEntryDate.length()==4){
            serviceEntryDate=serviceEntryDate+"0101";

        }

	    return serviceEntryDate;
	}

	/**
	 * Get Service Separation Date for imprecise dates to make them precise
	 * @param serviceSeparationDate
	 * @return serviceSeparationDate
	 *
	 * RTC Defect # 328325
	 */
	public String getPreciseServiceSeparationDate(String serviceSeparationDate){
		// get the imprecise service separation dates and calculate last day of the month if day is missing or 1231 if both month and day are missing and
	    if(serviceSeparationDate!=null && serviceSeparationDate.length()==6){
	        //Calculating no of days based on Month and year
            String date = serviceSeparationDate;
            //getting Month from Sub string of serviceSeparationDate
            Integer month = Integer.valueOf(serviceSeparationDate.substring(4,6));
            Integer year = Integer.valueOf(serviceSeparationDate.substring(0,4));
             GregorianCalendar calendar = new GregorianCalendar(year, month-1, 1);
                calendar.set(year, month-1, 1);
                int dayInt = calendar.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
                serviceSeparationDate=serviceSeparationDate+Integer.toString(dayInt);
        }

	    if(serviceSeparationDate != null && serviceSeparationDate.length()==4){
	           serviceSeparationDate=serviceSeparationDate+"1231";
	    }

	    return serviceSeparationDate;
	}
}