/*
 * MosP - Mind Open Source Project    http://www.mosp.jp/
 * Copyright (C) MIND Co., Ltd.       http://www.e-mind.co.jp/
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package jp.mosp.time.bean.impl;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jp.mosp.framework.base.BaseDtoInterface;
import jp.mosp.framework.base.MospException;
import jp.mosp.framework.base.MospParams;
import jp.mosp.framework.utils.DateUtility;
import jp.mosp.platform.base.PlatformBean;
import jp.mosp.platform.bean.human.HumanReferenceBeanInterface;
import jp.mosp.platform.bean.system.SectionReferenceBeanInterface;
import jp.mosp.platform.bean.workflow.WorkflowCommentReferenceBeanInterface;
import jp.mosp.platform.bean.workflow.WorkflowIntegrateBeanInterface;
import jp.mosp.platform.constant.PlatformConst;
import jp.mosp.platform.dto.human.HumanDtoInterface;
import jp.mosp.platform.dto.workflow.WorkflowCommentDtoInterface;
import jp.mosp.platform.dto.workflow.WorkflowDtoInterface;
import jp.mosp.time.bean.ApprovalInfoReferenceBeanInterface;
import jp.mosp.time.bean.AttendanceReferenceBeanInterface;
import jp.mosp.time.bean.DifferenceRequestReferenceBeanInterface;
import jp.mosp.time.bean.HolidayRequestReferenceBeanInterface;
import jp.mosp.time.bean.OvertimeRequestReferenceBeanInterface;
import jp.mosp.time.bean.SubHolidayRequestReferenceBeanInterface;
import jp.mosp.time.bean.SubstituteReferenceBeanInterface;
import jp.mosp.time.bean.WorkOnHolidayRequestReferenceBeanInterface;
import jp.mosp.time.bean.WorkTypeReferenceBeanInterface;
import jp.mosp.time.constant.TimeConst;
import jp.mosp.time.dao.settings.HolidayDaoInterface;
import jp.mosp.time.dto.settings.AttendanceDtoInterface;
import jp.mosp.time.dto.settings.DifferenceRequestDtoInterface;
import jp.mosp.time.dto.settings.HolidayDtoInterface;
import jp.mosp.time.dto.settings.HolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.ManagementRequestListDtoInterface;
import jp.mosp.time.dto.settings.OvertimeRequestDtoInterface;
import jp.mosp.time.dto.settings.RequestListDtoInterface;
import jp.mosp.time.dto.settings.SubHolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.SubstituteDtoInterface;
import jp.mosp.time.dto.settings.WorkOnHolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.WorkTypeDtoInterface;
import jp.mosp.time.dto.settings.impl.ManagementRequestListDto;
import jp.mosp.time.utils.TimeUtility;

/**
 * 承認情報参照クラス。
 */
public class ApprovalInfoReferenceBean extends PlatformBean implements ApprovalInfoReferenceBeanInterface {
	
	/**
	 * 区切文字(申請情報詳細)。
	 */
	protected static final String							SEPARATOR_REQUEST_INFO	= " ";
	
	/**
	 * 休暇種別管理DAO
	 */
	protected HolidayDaoInterface							holidayDao;
	
	/**
	 * 人事マスタ参照
	 */
	protected HumanReferenceBeanInterface					humanReference;
	
	/**
	 * 所属マスタ参照
	 */
	protected SectionReferenceBeanInterface					sectionReference;
	
	/**
	 * 勤務形態マスタ参照
	 */
	protected WorkTypeReferenceBeanInterface				workTypeReference;
	
	/**
	 * 勤怠データ参照
	 */
	protected AttendanceReferenceBeanInterface				attendanceReference;
	
	/**
	 * 残業申請参照
	 */
	protected OvertimeRequestReferenceBeanInterface			overtimeRequest;
	
	/**
	 * 休暇申請参照
	 */
	protected HolidayRequestReferenceBeanInterface			holidayRequest;
	
	/**
	 * 休日出勤申請参照
	 */
	protected WorkOnHolidayRequestReferenceBeanInterface	workOnHolidayRequest;
	
	/**
	 * 代休申請参照
	 */
	protected SubHolidayRequestReferenceBeanInterface		subHolidayRequest;
	
	/**
	 * 時差出勤申請参照
	 */
	protected DifferenceRequestReferenceBeanInterface		differenceRequest;
	
	/**
	 * ワークフローコメント参照
	 */
	protected WorkflowCommentReferenceBeanInterface			workflowCommentReference;
	
	/**
	 * ワークフロー統括
	 */
	protected WorkflowIntegrateBeanInterface				workflowIntegrate;
	
	/**
	 * 振替休日データ参照
	 */
	protected SubstituteReferenceBeanInterface				substituteReference;
	

	/**
	 * {@link PlatformBean#PlatformBean()}を実行する。<br>
	 */
	public ApprovalInfoReferenceBean() {
		super();
	}
	
	/**
	 * {@link PlatformBean#PlatformBean(MospParams, Connection)}を実行する。<br>
	 * @param mospParams MosPパラメータクラス
	 * @param connection DBコネクション
	 */
	public ApprovalInfoReferenceBean(MospParams mospParams, Connection connection) {
		super(mospParams, connection);
	}
	
	@Override
	public void initBean() throws MospException {
		humanReference = (HumanReferenceBeanInterface)createBean(HumanReferenceBeanInterface.class);
		sectionReference = (SectionReferenceBeanInterface)createBean(SectionReferenceBeanInterface.class);
		workTypeReference = (WorkTypeReferenceBeanInterface)createBean(WorkTypeReferenceBeanInterface.class);
		attendanceReference = (AttendanceReferenceBeanInterface)createBean(AttendanceReferenceBeanInterface.class);
		overtimeRequest = (OvertimeRequestReferenceBeanInterface)createBean(OvertimeRequestReferenceBeanInterface.class);
		holidayRequest = (HolidayRequestReferenceBeanInterface)createBean(HolidayRequestReferenceBeanInterface.class);
		workOnHolidayRequest = (WorkOnHolidayRequestReferenceBeanInterface)createBean(WorkOnHolidayRequestReferenceBeanInterface.class);
		subHolidayRequest = (SubHolidayRequestReferenceBeanInterface)createBean(SubHolidayRequestReferenceBeanInterface.class);
		differenceRequest = (DifferenceRequestReferenceBeanInterface)createBean(DifferenceRequestReferenceBeanInterface.class);
		workflowCommentReference = (WorkflowCommentReferenceBeanInterface)createBean(WorkflowCommentReferenceBeanInterface.class);
		workflowIntegrate = (WorkflowIntegrateBeanInterface)createBean(WorkflowIntegrateBeanInterface.class);
		holidayDao = (HolidayDaoInterface)createDao(HolidayDaoInterface.class);
		substituteReference = (SubstituteReferenceBeanInterface)createBean(SubstituteReferenceBeanInterface.class);
	}
	
	@Override
	public Map<String, Map<Long, WorkflowDtoInterface>> getApprovableMap(String personalId) throws MospException {
		// 承認可能勤怠申請情報群取得
		return workflowIntegrate.getApprovableMap(personalId, TimeUtility.getTimeFunctionSet());
	}
	
	@Override
	public Map<String, Map<Long, WorkflowDtoInterface>> getSubApprovableMap(String personalId,
			Map<String, Map<Long, WorkflowDtoInterface>> approvableMap) throws MospException {
		// 代理承認可能勤怠申請情報群取得
		return workflowIntegrate.getSubApprovableMap(personalId, TimeUtility.getTimeFunctionSet(),
				PlatformConst.WORKFLOW_TYPE_TIME, approvableMap);
	}
	
	@Override
	public List<ManagementRequestListDtoInterface> getApprovableList(
			Map<String, Map<Long, WorkflowDtoInterface>> approvableMap,
			Map<String, Map<Long, WorkflowDtoInterface>> subApprovableMap, String functionCode) throws MospException {
		// 承認可能勤怠申請情報リスト取得
		List<ManagementRequestListDtoInterface> list = getManagementRequestList(approvableMap, functionCode, false);
		// 代理承認可能勤怠申請情報リスト追加
		list.addAll(getManagementRequestList(subApprovableMap, functionCode, true));
		return list;
	}
	
	/**
	 * ワークフロー情報マップから勤怠申請情報リストを取得する。<br>
	 * 対象機能コードが指定されている場合は、対象機能コードのワークフローのみを抽出する。<br>
	 * @param workflowMap  ワークフロー情報マップ(勤怠)
	 * @param functionCode 対象機能コード
	 * @param isSubApprove 代理承認フラグ(true：代理承認、false：代理承認でない)
	 * @return 勤怠申請情報リスト
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected List<ManagementRequestListDtoInterface> getManagementRequestList(
			Map<String, Map<Long, WorkflowDtoInterface>> workflowMap, String functionCode, boolean isSubApprove)
			throws MospException {
		// 勤怠申請情報リスト準備
		List<ManagementRequestListDtoInterface> list = new ArrayList<ManagementRequestListDtoInterface>();
		// ワークフロー情報リスト準備
		List<WorkflowDtoInterface> workflowList = new ArrayList<WorkflowDtoInterface>();
		// ワークフロー情報マップをリストに追加
		if (functionCode.isEmpty()) {
			// ワークフロー情報リストを取得
			for (Map<Long, WorkflowDtoInterface> functionMap : workflowMap.values()) {
				workflowList.addAll(functionMap.values());
			}
		} else {
			// 指定機能コードのワークフロー情報リストを取得
			workflowList.addAll(workflowMap.get(functionCode).values());
		}
		// ワークフロー情報毎に処理
		for (WorkflowDtoInterface workflowDto : workflowList) {
			// 勤怠申請一覧情報を取得しリストに追加
			list.add(getManagementRequestListDto(workflowDto, isSubApprove));
		}
		return list;
	}
	
	/**
	 * 対象期間における有効ワークフロー情報一覧を取得する。<br>
	 * 申請者が対象申請者個人IDセットに含まれるもの、
	 * 或いは対象個人IDが承認者として含まれるものを抽出する。<br>
	 * @param personalId      対象個人ID
	 * @param fromDate        対象期間自
	 * @param toDate          対象期間至
	 * @param functionCodeSet 対象機能コードセット
	 * @param state           対象ワークフロー状態
	 * @param personalIdSet   対象申請者個人IDセット
	 * @return 有効ワークフロー情報一覧
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	@Override
	public List<ManagementRequestListDtoInterface> getEffectiveList(String personalId, Date fromDate, Date toDate,
			Set<String> functionCodeSet, String state, Set<String> personalIdSet, Set<String> subordinateIdSet)
			throws MospException {
		// 承認可能勤怠申請情報リスト準備
		List<ManagementRequestListDtoInterface> list = new ArrayList<ManagementRequestListDtoInterface>();
		// 有効ワークフロー情報リスト取得
		List<WorkflowDtoInterface> effectiveList = workflowIntegrate.getEffectiveList(personalId, fromDate, toDate,
				functionCodeSet, state, personalIdSet, subordinateIdSet);
		// 有効ワークフロー情報毎に処理
		for (WorkflowDtoInterface workflowDto : effectiveList) {
			// 勤怠申請一覧情報を取得しリストに追加
			list.add(getManagementRequestListDto(workflowDto, false));
		}
		return list;
	}
	
	/**
	 * 対象ワークフロー情報から、勤怠申請一覧情報を取得する。<br>
	 * @param workflowDto  対象ワークフロー情報
	 * @param isSubApprove 代理承認フラグ(true：代理承認、false：代理承認でない)
	 * @return 承認可能勤怠申請情報
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected ManagementRequestListDtoInterface getManagementRequestListDto(WorkflowDtoInterface workflowDto,
			boolean isSubApprove) throws MospException {
		// 勤怠申請一覧情報準備
		ManagementRequestListDtoInterface dto = new ManagementRequestListDto();
		// ワークフロー情報取得
		long workflow = workflowDto.getWorkflow();
		String personalId = workflowDto.getPersonalId();
		Date workflowDate = workflowDto.getWorkflowDate();
		String functionCode = workflowDto.getFunctionCode();
		// ワークフロー情報を勤怠申請一覧情報に設定
		dto.setPersonalId(personalId);
		dto.setRequestType(functionCode);
		dto.setRequestDate(workflowDto.getWorkflowDate());
		dto.setWorkflow(workflow);
		dto.setState(workflowDto.getWorkflowStatus());
		dto.setStage(workflowDto.getWorkflowStage());
		// 勤怠申請一覧情報設定値準備
		String employeeCode = "";
		String lastName = "";
		String firstName = "";
		String sectionCode = "";
		String requestInfo = "";
		// 人事基本情報取得
		HumanDtoInterface humanDto = humanReference.getHumanInfo(personalId, workflowDate);
		// 人事基本情報確認
		if (humanDto != null) {
			// 勤怠申請一覧情報に設定
			employeeCode = humanDto.getEmployeeCode();
			lastName = humanDto.getLastName();
			firstName = humanDto.getFirstName();
			sectionCode = humanDto.getSectionCode();
		}
		// 機能コード確認
		if (functionCode.equals(TimeConst.CODE_FUNCTION_WORK_MANGE)) {
			// 勤怠申請情報取得
			AttendanceDtoInterface attendanceDto = attendanceReference.findForWorkflow(workflow);
			requestInfo = getAttendanceInfo(attendanceDto);
		} else if (functionCode.equals(TimeConst.CODE_FUNCTION_OVER_WORK)) {
			// 残業申請情報取得
			OvertimeRequestDtoInterface overtimeDto = overtimeRequest.findForWorkflow(workflow);
			requestInfo = getOvertimeRequestInfo(overtimeDto);
		} else if (functionCode.equals(TimeConst.CODE_FUNCTION_VACATION)) {
			// 休暇申請情報取得
			HolidayRequestDtoInterface holidayDto = holidayRequest.findForWorkflow(workflow);
			requestInfo = getHolidayRequestInfo(holidayDto);
		} else if (functionCode.equals(TimeConst.CODE_FUNCTION_WORK_HOLIDAY)) {
			// 振出休出申請情報取得
			WorkOnHolidayRequestDtoInterface workOnHolidayDto = workOnHolidayRequest.findForWorkflow(workflow);
			requestInfo = getWorkOnHolidayRequestInfo(workOnHolidayDto);
		} else if (functionCode.equals(TimeConst.CODE_FUNCTION_COMPENSATORY_HOLIDAY)) {
			// 代休申請情報取得
			SubHolidayRequestDtoInterface subHolidayDto = subHolidayRequest.findForWorkflow(workflow);
			requestInfo = getSubHolidayRequestInfo(subHolidayDto);
		} else if (functionCode.equals(TimeConst.CODE_FUNCTION_DIFFERENCE)) {
			// 時差出勤申請情報取得
			DifferenceRequestDtoInterface differenceDto = differenceRequest.findForWorkflow(workflow);
			requestInfo = getDifferenceRequestInfo(differenceDto);
		}
		// 勤怠申請一覧情報設定値を勤怠申請一覧情報に設定
		dto.setEmployeeCode(employeeCode);
		dto.setLastName(lastName);
		dto.setFirstName(firstName);
		dto.setSectionCode(sectionCode);
		dto.setRequestInfo(requestInfo);
		// 代理情報設定
		if (isSubApprove) {
			dto.setRequestInfo(mospParams.getName("Substitution") + SEPARATOR_REQUEST_INFO + dto.getRequestInfo());
		}
		return dto;
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 勤怠情報DTO
	 * @return 申請情報詳細
	 * @throws MospException SQLの作成に失敗した場合、或いはSQL例外が発生した場合
	 */
	protected String getAttendanceInfo(AttendanceDtoInterface dto) throws MospException {
		// 始業・終業・直行・直帰・遅刻・早退・残業等必要な情報を表示する
		StringBuffer sb = new StringBuffer();
		DifferenceRequestDtoInterface differenceRequestDto = differenceRequest.findForKeyOnWorkflow(
				dto.getPersonalId(), dto.getWorkDate());
		if (differenceRequestDto == null) {
			WorkTypeDtoInterface workTypeDto = workTypeReference.findForInfo(dto.getWorkTypeCode(), dto.getWorkDate());
			if (workTypeDto != null) {
				// 勤務形態
				sb.append(workTypeDto.getWorkTypeAbbr());
				sb.append(SEPARATOR_REQUEST_INFO);
			}
		} else {
			WorkflowDtoInterface workflowDto = workflowIntegrate.getLatestWorkflowInfo(differenceRequestDto
				.getWorkflow());
			if (workflowDto != null && PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 承認済の場合
				sb.append(differenceRequest.getDifferenceAbbr(differenceRequestDto.getDifferenceType()));
				sb.append(SEPARATOR_REQUEST_INFO);
			}
		}
		if (dto.getDirectStart() == 1) {
			// 直行
			sb.append(mospParams.getName("DirectStart"));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getDirectEnd() == 1) {
			// 直帰
			sb.append(mospParams.getName("DirectEnd"));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getStartTime() != null) {
			// 始業
			sb.append(mospParams.getName("StartWork"));
			sb.append(mospParams.getName("Colon"));
			sb.append(DateUtility.getStringTime(dto.getStartTime(), dto.getWorkDate()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getEndTime() != null) {
			// 終業
			sb.append(mospParams.getName("EndWork"));
			sb.append(mospParams.getName("Colon"));
			sb.append(DateUtility.getStringTime(dto.getEndTime(), dto.getWorkDate()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getLateTime() > 0) {
			// 遅刻
			sb.append(mospParams.getName("Tardiness"));
			sb.append(mospParams.getName("Colon"));
			sb.append(getHour(dto.getLateTime()));
			sb.append(mospParams.getName("Dot"));
			sb.append(getStringMinute(dto.getLateTime()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getLeaveEarlyTime() > 0) {
			// 早退
			sb.append(mospParams.getName("LeaveEarly"));
			sb.append(mospParams.getName("Colon"));
			sb.append(getHour(dto.getLeaveEarlyTime()));
			sb.append(mospParams.getName("Dot"));
			sb.append(getStringMinute(dto.getLeaveEarlyTime()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getOvertime() > 0) {
			// 残業
			sb.append(mospParams.getName("OvertimeWork"));
			sb.append(mospParams.getName("Colon"));
			sb.append(getHour(dto.getOvertime()));
			sb.append(mospParams.getName("Dot"));
			sb.append(getStringMinute(dto.getOvertime()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (dto.getLateNightTime() > 0) {
			// 深夜
			sb.append(mospParams.getName("Midnight"));
			sb.append(mospParams.getName("Colon"));
			sb.append(getHour(dto.getLateNightTime()));
			sb.append(mospParams.getName("Dot"));
			sb.append(getStringMinute(dto.getLateNightTime()));
			sb.append(SEPARATOR_REQUEST_INFO);
		}
		if (!dto.getTimeComment().isEmpty()) {
			// 勤怠コメント
//			sb.append(mospParams.getName("WorkManage"));
//			sb.append(mospParams.getName("Comment"));
//			sb.append(mospParams.getName("Colon"));
			sb.append(dto.getTimeComment());
		}
		return sb.toString();
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 残業申請DTO
	 * @return 申請情報詳細
	 */
	protected String getOvertimeRequestInfo(OvertimeRequestDtoInterface dto) {
		// 表示例 予定:2時間30分 残業区分：勤務後残業 理由:顧客サポート
		StringBuffer sb = new StringBuffer();
		// 予定
		sb.append(mospParams.getName("Schedule") + mospParams.getName("Colon"));
		sb.append((dto.getRequestTime() / 60) + mospParams.getName("Time"));
		sb.append((dto.getRequestTime() % 60) + mospParams.getName("Minutes"));
		// 空欄
		sb.append(SEPARATOR_REQUEST_INFO);
		// 残業区分
		sb.append(mospParams.getName("Type") + mospParams.getName("Colon"));
		sb.append(getCodeName(dto.getOvertimeType(), TimeConst.CODE_OVER_TIME_TYPE));
		// 空欄
		sb.append(SEPARATOR_REQUEST_INFO);
		// 理由
		sb.append(mospParams.getName("Reason") + mospParams.getName("Colon") + dto.getRequestReason());
		return sb.toString();
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 休暇申請DTO
	 * @return 申請情報詳細
	 * @throws MospException SQLの作成に失敗した場合、或いはSQL例外が発生した場合
	 */
	protected String getHolidayRequestInfo(HolidayRequestDtoInterface dto) throws MospException {
		int holidayType1 = dto.getHolidayType1();
		// 表示例 結婚休暇
		StringBuffer sb = new StringBuffer();
		sb.append(mospParams.getName("Wave"));
		sb.append(DateUtility.getStringDateAndDay(dto.getRequestEndDate()));
		sb.append(SEPARATOR_REQUEST_INFO);
		if (holidayType1 == 1) {
			if (Integer.toString(1).equals(dto.getHolidayType2())) {
				// 有給休暇
				sb.append(mospParams.getName("Salaried"));
				sb.append(mospParams.getName("Vacation"));
			} else if (Integer.toString(2).equals(dto.getHolidayType2())) {
				// ストック休暇
				sb.append(mospParams.getName("Stock"));
				sb.append(mospParams.getName("Vacation"));
			}
		} else if (holidayType1 == 2) {
			// 特別休暇
			sb.append(mospParams.getName("Specially"));
			sb.append(mospParams.getName("Vacation"));
		} else if (holidayType1 == 3) {
			// その他休暇
			sb.append(mospParams.getName("Others"));
		} else if (holidayType1 == 4) {
			// 欠勤
			sb.append(mospParams.getName("Absence"));
		}
		if (holidayType1 == 2 || holidayType1 == 3 || holidayType1 == 4) {
			// 特別休暇、その他休暇又は欠勤
			HolidayDtoInterface holidayDto = holidayDao.findForInfo(dto.getHolidayType2(), dto.getRequestStartDate(),
					holidayType1);
			if (holidayDto != null) {
				sb.append(SEPARATOR_REQUEST_INFO);
				sb.append(holidayDto.getHolidayAbbr());
			}
		}
		sb.append(SEPARATOR_REQUEST_INFO);
		// 休暇範囲設定
		sb.append(mospParams.getProperties().getCodeItemName(TimeConst.CODE_HOLIDAY_TYPE3_RANGE1,
				String.valueOf(dto.getHolidayRange())));
		sb.append(SEPARATOR_REQUEST_INFO);
		// 休暇理由
		sb.append(mospParams.getName("Vacation"));
		sb.append(mospParams.getName("Reason"));
		sb.append(mospParams.getName("Colon"));
		sb.append(dto.getRequestReason());
		return sb.toString();
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 振出休出申請DTO
	 * @return 申請情報詳細
	 * @throws MospException 例外処理発生時
	 */
	protected String getWorkOnHolidayRequestInfo(WorkOnHolidayRequestDtoInterface dto) throws MospException {
		StringBuffer sb = new StringBuffer();
		String startTime = DateUtility.getStringTime(dto.getStartTime(), dto.getRequestDate());
		String endTime = DateUtility.getStringTime(dto.getEndTime(), dto.getRequestDate());
		if (!startTime.isEmpty() && !endTime.isEmpty()) {
			// 勤務予定
			sb.append(mospParams.getName("Work"));
			sb.append(mospParams.getName("Schedule"));
			sb.append(mospParams.getName("Colon"));
			sb.append(startTime);
			sb.append(mospParams.getName("Wave"));
			sb.append(endTime);
			// 空欄
			sb.append(" ");
		}
		if (dto.getSubstitute() == TimeConst.CODE_WORK_ON_HOLIDAY_SUBSTITUTE_ON) {
			// 振替出勤の場合
			List<SubstituteDtoInterface> list = substituteReference.getSubstituteList(dto.getWorkflow());
			for (SubstituteDtoInterface substituteDto : list) {
				// 振替休日
				sb.append(mospParams.getName("Transfer"));
				sb.append(mospParams.getName("Holiday"));
				sb.append(mospParams.getName("Colon"));
				sb.append(DateUtility.getStringDateAndDay(substituteDto.getSubstituteDate()));
				// 空欄
				sb.append(" ");
				break;
			}
		}
		// 申請理由
		sb.append(mospParams.getName("Application"));
		sb.append(mospParams.getName("Reason"));
		sb.append(mospParams.getName("Colon"));
		sb.append(dto.getRequestReason());
		return sb.toString();
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 代休申請DTO
	 * @return 申請情報詳細
	 * @throws MospException 例外処理発生時
	 */
	protected String getSubHolidayRequestInfo(SubHolidayRequestDtoInterface dto) throws MospException {
		// 表示例 休出:2010/12/1 勤務7時間00分
		StringBuffer sb = new StringBuffer();
		int type = dto.getWorkDateSubHolidayType();
		if (type == 1 || type == 2) {
			// 休出
			sb.append(mospParams.getName("WorkingHoliday"));
		} else if (type == 3) {
			// 深夜
			sb.append(mospParams.getName("Midnight"));
		}
		sb.append(mospParams.getName("Colon"));
		sb.append(DateUtility.getStringDateAndDay(dto.getWorkDate()));
		// 空欄
		sb.append(SEPARATOR_REQUEST_INFO);
		sb.append(mospParams.getName("Work"));
		sb.append(mospParams.getName("Colon"));
		AttendanceDtoInterface attendanceDto = attendanceReference
			.findForKey(dto.getPersonalId(), dto.getWorkDate(), 1);
		if (attendanceDto == null) {
			sb.append(0);
			sb.append(mospParams.getName("Time"));
			sb.append("00");
			sb.append(mospParams.getName("Minutes"));
		} else {
			sb.append(getHour(attendanceDto.getWorkTime()));
			sb.append(mospParams.getName("Time"));
			sb.append(getStringMinute(attendanceDto.getWorkTime()));
			sb.append(mospParams.getName("Minutes"));
		}
		// 休暇範囲設定
		sb.append(SEPARATOR_REQUEST_INFO);
		sb.append(mospParams.getProperties().getCodeItemName(TimeConst.CODE_HOLIDAY_TYPE3_RANGE1,
				String.valueOf(dto.getHolidayRange())));
		return sb.toString();
	}
	
	/**
	 * 申請情報詳細の設定
	 * @param dto 時差出勤申請DTO
	 * @return 申請情報詳細
	 */
	protected String getDifferenceRequestInfo(DifferenceRequestDtoInterface dto) {
		StringBuffer sb = new StringBuffer();
		sb.append(mospParams.getName("Application"));
		sb.append(mospParams.getName("Colon"));
		sb.append(differenceRequest.getDifferenceTime(dto));
		sb.append(SEPARATOR_REQUEST_INFO);
		sb.append(mospParams.getName("Reason"));
		sb.append(mospParams.getName("Colon"));
		sb.append(dto.getRequestReason());
		return sb.toString();
	}
	
	@Override
	public BaseDtoInterface getRequestDtoForWorkflow(long workflow, boolean isApproval) throws MospException {
		WorkflowDtoInterface dto = workflowIntegrate.getLatestWorkflowInfo(workflow);
		if (dto != null) {
			// 下書きを除く
			if (isApproval && PlatformConst.CODE_STATUS_DRAFT.equals(dto.getWorkflowStatus())) {
				return null;
			}
			// 勤怠データ
			if (TimeConst.CODE_FUNCTION_WORK_MANGE.equals(dto.getFunctionCode())) {
				return attendanceReference.findForWorkflow(workflow);
			}
			// 残業申請
			if (TimeConst.CODE_FUNCTION_OVER_WORK.equals(dto.getFunctionCode())) {
				return overtimeRequest.findForWorkflow(workflow);
			}
			// 休暇申請
			if (TimeConst.CODE_FUNCTION_VACATION.equals(dto.getFunctionCode())) {
				return holidayRequest.findForWorkflow(workflow);
			}
			// 休日出勤
			if (TimeConst.CODE_FUNCTION_WORK_HOLIDAY.equals(dto.getFunctionCode())) {
				return workOnHolidayRequest.findForWorkflow(workflow);
			}
			// 代休申請
			if (TimeConst.CODE_FUNCTION_COMPENSATORY_HOLIDAY.equals(dto.getFunctionCode())) {
				return subHolidayRequest.findForWorkflow(workflow);
			}
			// 時差出勤
			if (TimeConst.CODE_FUNCTION_DIFFERENCE.equals(dto.getFunctionCode())) {
				return differenceRequest.findForWorkflow(workflow);
			}
		}
		return null;
	}
	
	@Override
	public void setWorkflowInfo(RequestListDtoInterface dto, WorkflowDtoInterface workflowDto) throws MospException {
		if (dto != null && workflowDto != null) {
			WorkflowCommentDtoInterface commentDto = workflowCommentReference.getLatestWorkflowCommentInfo(workflowDto
				.getWorkflow());
			if (commentDto != null) {
				// 承認段階
				dto.setStage(workflowDto.getWorkflowStage());
				// 承認状況
				dto.setState(workflowDto.getWorkflowStatus());
				String approverName = humanReference.getHumanName(commentDto.getPersonalId(), commentDto
					.getWorkflowDate());
				// THINK 次の承認者の個人IDを取得。
				
				// 下書き、申請、完了の場合
				if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())
						|| PlatformConst.CODE_STATUS_APPLY.equals(workflowDto.getWorkflowStatus())
						|| PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					approverName = "";
				}
				// 承認者名
				dto.setApproverName(approverName);
			}
		}
	}
	
	@Override
	public String[][][] getArrayForApproverSetting(String personalId, Date targetDate, int workflowType)
			throws MospException {
		// 承認ルート人事マスタ一覧
		List<List<String[]>> approvalRouteList = workflowIntegrate.getRouteApproverList(personalId, targetDate,
				workflowType);
		// エラー確認
		if (mospParams.hasErrorMessage()) {
			return new String[0][][];
		}
		// 承認階層分の申請用承認者情報配列準備
		String[][][] aryApproverSetting = new String[approvalRouteList.size()][][];
		// 承認階層インデックス準備
		int approvalLevel = 0;
		// 承認階層毎に申請用承認者情報を作成
		for (List<String[]> approverList : approvalRouteList) {
			// i次承認者配列作成用リスト準備
			List<String[]> list = new ArrayList<String[]>();
			// 承認者リストから申請用承認者情報を作成
			for (String[] approver : approverList) {
				// 申請用承認者情報配列作成用リストに追加
				list.add(approver);
			}
			aryApproverSetting[approvalLevel++] = list.toArray(new String[list.size()][]);
		}
		return aryApproverSetting;
	}
	
	/**
	 * 時間取得。
	 * @param time 時間
	 * @return 時間
	 */
	protected int getHour(int time) {
		return time / TimeConst.CODE_DEFINITION_HOUR;
	}
	
	/**
	 * 分取得。
	 * @param time 時間
	 * @return 分
	 */
	protected int getMinute(int time) {
		return Math.abs(time) % TimeConst.CODE_DEFINITION_HOUR;
	}
	
	/**
	 * 分取得。
	 * @param time 時間
	 * @return 分
	 */
	protected String getStringMinute(int time) {
		int minute = getMinute(time);
		if (minute < 10) {
			// 10より小さい場合
			StringBuffer sb = new StringBuffer();
			sb.append(0);
			sb.append(minute);
			return sb.toString();
		}
		return Integer.toString(minute);
	}
	
}
