/*
 * 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.management.action;

import java.util.Date;
import java.util.List;

import jp.mosp.framework.base.BaseVo;
import jp.mosp.framework.base.MospException;
import jp.mosp.framework.utils.DateUtility;
import jp.mosp.framework.utils.TopicPathUtility;
import jp.mosp.platform.bean.workflow.WorkflowIntegrateBeanInterface;
import jp.mosp.platform.constant.PlatformConst;
import jp.mosp.platform.constant.PlatformMessageConst;
import jp.mosp.platform.dto.workflow.SubApproverDtoInterface;
import jp.mosp.platform.dto.workflow.WorkflowCommentDtoInterface;
import jp.mosp.platform.dto.workflow.WorkflowDtoInterface;
import jp.mosp.time.base.TimeAction;
import jp.mosp.time.base.TimeBean;
import jp.mosp.time.constant.TimeConst;
import jp.mosp.time.dto.settings.AttendanceCorrectionDtoInterface;
import jp.mosp.time.dto.settings.AttendanceDtoInterface;
import jp.mosp.time.dto.settings.DifferenceRequestDtoInterface;
import jp.mosp.time.dto.settings.GoOutDtoInterface;
import jp.mosp.time.dto.settings.HolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.OvertimeRequestDtoInterface;
import jp.mosp.time.dto.settings.RestDtoInterface;
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.management.vo.ApprovalCardVo;

/**
 * 未承認情報一覧画面で確認した承認すべき申請情報の個別承認を行う。<br>
 * <br>
 * 以下のコマンドを扱う。<br>
 * <ul><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_ATTENDANCE}
 * </li><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_OVERTIME}
 * </li><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_HOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_WORKONHOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_SUBHOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_CONFIRMATION_DIFFERENCE}
 * </li><li>
 * {@link #CMD_APPROVAL_ATTENDANCE}
 * </li><li>
 * {@link #CMD_APPROVAL_OVERTIME}
 * </li><li>
 * {@link #CMD_APPROVAL_HOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_WORKONHOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_SUBHOLIDAY}
 * </li><li>
 * {@link #CMD_APPROVAL_DIFFERENCE}
 * </li><li>
 * {@link #CMD_APPROVAL}
 * </li><li>
 * {@link #CMD_REVERTING}
 * </li><li>
 * {@link #CMD_DELETE}
 * </li></ul>
 */
public class ApprovalCardAction extends TimeAction {
	
	/**
	 * 勤怠承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが日々勤怠のレコードを選択した際に実行。<br>
	 * 勤怠申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、勤怠承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_ATTENDANCE	= "TM2320";
	
	/**
	 * 残業承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが残業申請のレコードを選択した際に実行。<br>
	 * 残業申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、残業承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_OVERTIME		= "TM2330";
	
	/**
	 * 休暇承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが休暇申請のレコードを選択した際に実行。<br>
	 * 休暇申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、休暇承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_HOLIDAY		= "TM2340";
	
	/**
	 * 休日出勤承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが休日出勤のレコードを選択した際に実行。<br>
	 * 休日出勤申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、休日出勤承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_WORKONHOLIDAY	= "TM2350";
	
	/**
	 * 代休承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが代休申請のレコードを選択した際に実行。<br>
	 * 代休申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、代休承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_SUBHOLIDAY	= "TM2360";
	
	/**
	 * 時差出勤承認確認画面表示コマンド。<br>
	 * <br>
	 * 申請情報確認画面で申請カテゴリが時差出勤申請のレコードを選択した際に実行。<br>
	 * 時差出勤申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、時差出勤承認コメント欄がテキストボックスとなる。<br>
	 * 画面下部のボタン欄は取消ボタンがクリック可能な状態で表示される。<br>
	 */
	public static final String	CMD_APPROVAL_CONFIRMATION_DIFFERENCE	= "TM2370";
	
	/**
	 * 勤怠承認画面表示コマンド。<br>
	 * <br>
	 * 未承認情報一覧画面で申請カテゴリが日々勤怠のレコードを選択した際に実行。<br>
	 * 勤怠申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、勤怠承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_ATTENDANCE					= "TM2321";
	
	/**
	 * 残業承認画面表示コマンド。<br>
	 * <br>
	 * 残業承認画面表示コマンド。未承認情報一覧画面で申請カテゴリが残業申請のレコードを選択した際に実行。<br>
	 * 残業申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、残業承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_OVERTIME					= "TM2331";
	
	/**
	 * 休暇承認画面表示コマンド。<br>
	 * <br>
	 * 未承認情報一覧画面で申請カテゴリが休暇申請のレコードを選択した際に実行。<br>
	 * 休暇申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、休暇承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_HOLIDAY					= "TM2341";
	
	/**
	 * 休日出勤承認画面表示コマンド。<br>
	 * <br>
	 * 未承認情報一覧画面で申請カテゴリが休日出勤のレコードを選択した際に実行。<br>
	 * 休日出勤申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、休日出勤承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_WORKONHOLIDAY				= "TM2351";
	
	/**
	 * 代休承認画面表示コマンド。<br>
	 * <br>
	 * 未承認情報一覧画面で申請カテゴリが代休申請のレコードを選択した際に実行。<br>
	 * 代休申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、代休承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_SUBHOLIDAY					= "TM2361";
	
	/**
	 * 時差出勤承認画面表示コマンド。<br>
	 * <br>
	 * 未承認情報一覧画面で申請カテゴリが時差出勤申請のレコードを選択した際に実行。<br>
	 * 時差出勤申請情報の表示欄ヘッダの背景色を#CCFFCCに切り替え、時差出勤承認コメント欄がテキストボックスとなる。<br>
	 */
	public static final String	CMD_APPROVAL_DIFFERENCE					= "TM2371";
	
	/**
	 * 承認コマンド。<br>
	 * <br>
	 * 各種コメント欄にコメントが入力されているかを確認後、現在表示している申請情報の承認を行う。<br>
	 * コメントが入力さずにボタンがクリックされた場合はエラーメッセージにて通知。処理は実行されない。<br>
	 */
	public static final String	CMD_APPROVAL							= "TM2325";
	
	/**
	 * 差戻コマンド。<br>
	 * <br>
	 * 各種コメント欄にコメントが入力されているかを確認後、現在表示している申請情報の差戻しを行う。<br>
	 * コメントが入力さずにボタンがクリックされた場合はエラーメッセージにて通知。処理は実行されない。<br>
	 */
	public static final String	CMD_REVERTING							= "TM2326";
	
	/**
	 * 取消コマンド。<br>
	 * <br>
	 * 現在表示している承認完了済の申請情報の承認取消を行う。該当レコードの状態を「取消」に切り替える。<br>
	 */
	public static final String	CMD_DELETE								= "TM2327";
	
	/**
	 * 区切文字(修正情報等)。
	 */
	public static final String	SEPARATOR								= " ";
	

	/**
	 * {@link TimeAction#TimeAction()}を実行する。<br>
	 */
	public ApprovalCardAction() {
		super();
	}
	
	@Override
	protected BaseVo getSpecificVo() {
		return new ApprovalCardVo();
	}
	
	@Override
	public void action() throws MospException {
		// コマンド毎の処理
		if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_ATTENDANCE)) {
			// 勤怠承認確認画面表示
			prepareVo(false, false);
			approvalAttendance(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_OVERTIME)) {
			// 残業承認確認画面表示
			prepareVo(false, false);
			approvalOvertime(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_HOLIDAY)) {
			// 休暇承認確認画面表示
			prepareVo(false, false);
			approvalHoliday(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_WORKONHOLIDAY)) {
			// 振出・休出承認確認画面表示
			prepareVo(false, false);
			approvalWorkOnHoliday(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_SUBHOLIDAY)) {
			// 代休承認確認画面表示
			prepareVo(false, false);
			approvalSubHoliday(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_CONFIRMATION_DIFFERENCE)) {
			// 時差出勤確認承認画面表示
			prepareVo(false, false);
			approvalDifference(true);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_ATTENDANCE)) {
			// 勤怠承認画面表示
			prepareVo(false, false);
			approvalAttendance(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_OVERTIME)) {
			// 残業承認画面表示
			prepareVo(false, false);
			approvalOvertime(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_HOLIDAY)) {
			// 休暇承認画面表示
			prepareVo(false, false);
			approvalHoliday(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_WORKONHOLIDAY)) {
			// 振出・休出承認画面表示
			prepareVo(false, false);
			approvalWorkOnHoliday(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_SUBHOLIDAY)) {
			// 代休承認画面表示
			prepareVo(false, false);
			approvalSubHoliday(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL_DIFFERENCE)) {
			// 時差出勤承認画面表示
			prepareVo(false, false);
			approvalDifference(false);
		} else if (mospParams.getCommand().equals(CMD_APPROVAL)) {
			// 承認
			prepareVo();
			approval();
		} else if (mospParams.getCommand().equals(CMD_REVERTING)) {
			// 差戻
			prepareVo();
			reverting();
		} else if (mospParams.getCommand().equals(CMD_DELETE)) {
			// 削除	
			prepareVo();
			cancel();
		}
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(勤怠)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalAttendance(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(勤怠)
		vo.setAttendance(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(残業)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalOvertime(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(残業)
		vo.setOvertime(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(休暇)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalHoliday(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(休暇)
		vo.setHoliday(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(振出休出)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalWorkOnHoliday(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(振出休出)
		vo.setWorkOnHoliday(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(代休)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalSubHoliday(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(代休)
		vo.setSubHoliday(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 申請確認詳細或いは未承認確認画面(時差出勤)表示処理を行う。<br>
	 * @param isConfirmation 申請確認詳細フラグ
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void approvalDifference(boolean isConfirmation) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 申請確認詳細フラグ設定(未承認情報詳細)
		vo.setConfirmation(isConfirmation);
		// 申請カテゴリ設定(時差出勤)
		vo.setDifference(true);
		// 初期値設定
		setInitValues();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 承認処理を行う。<br>
	 * @throws MospException 例外処理発生時
	 */
	protected void approval() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 承認処理
		time().timeApproval().approve(vo.getWorkflow(), getWorkflowComment());
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			// 登録失敗メッセージ設定
			addInsertFailedMessage();
			return;
		}
		// コミット
		commit();
		// 承認成功メッセージ設定
		addApprovalMessage();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 差戻処理を行う。<br>
	 * @throws MospException 例外処理発生時
	 */
	protected void reverting() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 差戻処理
		time().timeApproval().revert(vo.getWorkflow(), getWorkflowComment());
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			// 登録失敗メッセージ設定
			addInsertFailedMessage();
			return;
		}
		// コミット
		commit();
		// 承認成功メッセージ設定
		addSendingBackMessage();
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 承認解除処理を行う。<br>
	 * @throws MospException 例外処理発生時
	 */
	protected void cancel() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 承認解除
		time().timeApproval().cancel(vo.getWorkflow(), null);
		// 承認解除結果確認
		if (mospParams.hasErrorMessage()) {
			// 取消失敗メッセージ設定
			addDeleteHistoryFailedMessage();
			return;
		}
		// コミット
		commit();
		// 承認解除成功メッセージ設定
		mospParams.addMessage(PlatformMessageConst.MSG_PROCESS_SUCCEED, new String[]{ mospParams.getName("Approval")
				+ mospParams.getName("Release") });
		// 申請情報設定
		setRequestValues();
	}
	
	/**
	 * 各種申請情報を取得し、設定する。<br>
	 * 申請カテゴリで設定する申請を判断し、
	 * 申請確認詳細フラグとワークフロー情報でボタン要否を判断する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setRequestValues() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 対象ワークフロー番号取得
		long workflow = vo.getWorkflow();
		// 申請カテゴリ毎に申請情報を設定
		if (vo.isAttendance()) {
			// 勤怠申請情報設定
			setAttendanceValues();
			// その他申請情報設定
			setOtherRequestValues();
		} else if (vo.isOvertime()) {
			// 残業申請情報取得及び設定
			setOvertimeValues(timeReference().overtimeRequest().findForWorkflow(workflow));
		} else if (vo.isHoliday()) {
			// 休暇申請情報設定
			setHolidayValues(timeReference().holidayRequest().findForWorkflow(workflow));
		} else if (vo.isWorkOnHoliday()) {
			// 振出休出申請情報設定
			setWorkOnHolidayValues(timeReference().workOnHolidayRequest().findForWorkflow(workflow));
		} else if (vo.isSubHoliday()) {
			// 代休申請情報設定
			setSubHolidayValues(timeReference().subHolidayRequest().findForWorkflow(workflow));
		} else if (vo.isDifference()) {
			// 時差出勤申請情報設定
			setDifferenceValues(timeReference().differenceRequest().findForWorkflow(workflow));
		}
		// ボタン要否フラグ設定
		setButtonFlag();
	}
	
	/**
	 * VOに初期値を設定する。<br>
	 * 対象ワークフロー番号を取得し、設定する。<br>
	 * ワークフロー情報から人事情報を取得し、設定する。<br>
	 * 各種フラグ等を初期化する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	public void setInitValues() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 表示コマンド確認
		if (vo.isConfirmation()) {
			// パンくずリスト名称設定(申請確認詳細の場合)
			TopicPathUtility.setTopicPathName(mospParams, vo.getClassName(), getNameRequestCard());
		}
		// 対象ワークフロー番号取得
		long workflow = getTargetWorkflow();
		// 対象ワークフロー番号を設定
		vo.setWorkflow(workflow);
		// 対象ワークフロー番号からワークフロー情報を取得
		WorkflowDtoInterface workflowDto = reference().workflow().getLatestWorkflowInfo(workflow);
		// 対象個人ID取得
		String personalId = workflowDto.getPersonalId();
		// 対象日取得
		Date targetDate = workflowDto.getWorkflowDate();
		// 人事情報設定
		setEmployeeInfo(personalId, targetDate);
		// 対象日設定
		vo.setLblYear(DateUtility.getStringYear(targetDate));
		vo.setLblMonth(DateUtility.getStringMonth(targetDate));
		vo.setLblDay(DateUtility.getStringDay(targetDate));
	}
	
	/**
	 * 勤怠申請情報を取得し、設定する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setAttendanceValues() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 対象個人ID、対象日、対象ワークフロー取得
		String personalId = vo.getPersonalId();
		Date targetDate = vo.getTargetDate();
		long workflow = vo.getWorkflow();
		// ワークフロー情報取得
		WorkflowDtoInterface workflowDto = reference().workflow().getLatestWorkflowInfo(workflow);
		// 勤怠データ取得
		AttendanceDtoInterface dto = timeReference().attendance().findForWorkflow(workflow);
		// 申請情報及びワークフロー情報確認
		if (dto == null || workflowDto == null) {
			return;
		}
		// 出退勤情報設定
		vo.setLblStartTime(getStringTimeMinutes(dto.getStartTime()));
		vo.setLblEndTime(DateUtility.getStringHour(dto.getEndTime(), dto.getWorkDate()) + mospParams.getName("Hour")
				+ getStringMinute(dto.getEndTime()) + mospParams.getName("Minutes"));
		vo.setLblWorkTime(getTimeTimeFormat(dto.getWorkTime()));
		// 勤務形態設定
		vo.setLblWorkType(getWorkTypeAbbrStartTimeEndTime(dto));
		// 直行直帰
		String directWorkManage = "";
		if (dto.getDirectStart() == 1) {
			directWorkManage = mospParams.getName("DirectStart") + SEPARATOR;
		}
		if (dto.getDirectEnd() == 1) {
			directWorkManage = directWorkManage + mospParams.getName("DirectEnd");
		}
		vo.setLblDirectWorkManage(directWorkManage);
		// 勤怠コメント設定
		vo.setLblTimeComment(dto.getTimeComment());
		// 休憩情報
		vo.setLblRestTime(getTimeTimeFormat(dto.getRestTime()));
		vo.setLblOverRestTime(getTimeTimeFormat(dto.getOverRestTime()));
		vo.setLblNightRestTime(getTimeTimeFormat(dto.getNightRestTime()));
		vo.setLblPublicTime(getTimeTimeFormat(dto.getPublicTime()));
		vo.setLblPrivateTime(getTimeTimeFormat(dto.getPrivateTime()));
		// 遅刻早退情報
		vo.setLblLateTime(getTimeTimeFormat(dto.getLateTime()));
		vo.setLblLateReason(getCodeName(dto.getLateReason(), TimeConst.CODE_REASON_OF_LATE));
		vo.setLblLateCertificate(getCodeName(dto.getLateCertificate(), TimeConst.CODE_ALLOWANCE));
		vo.setLblLateComment(dto.getLateComment());
		vo.setLblLeaveEarlyTime(getTimeTimeFormat(dto.getLeaveEarlyTime()));
		vo.setLblLeaveEarlyReason(getCodeName(dto.getLeaveEarlyReason(), TimeConst.CODE_REASON_OF_LEAVE_EARLY));
		vo.setLblLeaveEarlyCertificate(getCodeName(dto.getLeaveEarlyCertificate(), TimeConst.CODE_ALLOWANCE));
		vo.setLblLeaveEarlyComment(dto.getLeaveEarlyComment());
		// 割増情報
		vo.setLblOverTimeIn(getTimeTimeFormat(dto.getOvertime()));
		vo.setLblOverTimeOut(getTimeTimeFormat(dto.getOvertimeOut()));
		vo.setLblLateNightTime(getTimeTimeFormat(dto.getLateNightTime()));
		vo.setLblSpecificWorkTimeIn(getTimeTimeFormat(dto.getSpecificWorkTime()));
		vo.setLblLegalWorkTime(getTimeTimeFormat(dto.getLegalWorkTime()));
		vo.setLblDecreaseTime(getTimeTimeFormat(dto.getDecreaseTime()));
		// 残業実績時間
		vo.setLblOverTimeResult(getTimeTimeFormat(dto.getOvertime()));
		// 休憩情報取得
		List<RestDtoInterface> restList = timeReference().rest().getRestList(personalId, targetDate,
				TimeBean.TIMES_WORK_DEFAULT);
		// 休憩情報設定
		for (RestDtoInterface restDto : restList) {
			switch (restDto.getRest()) {
				case 1:
					vo.setLblRestTime1(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				case 2:
					vo.setLblRestTime2(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				case 3:
					vo.setLblRestTime3(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				case 4:
					vo.setLblRestTime4(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				case 5:
					vo.setLblRestTime5(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				case 6:
					vo.setLblRestTime6(getTimeWaveFormat(restDto.getRestStart(), restDto.getRestEnd()));
					break;
				default:
					break;
			}
		}
		// 公用外出情報取得
		List<GoOutDtoInterface> goOutList = timeReference().goOut().getPublicGoOutList(personalId, targetDate);
		// 公用外出情報設定
		for (GoOutDtoInterface goOutDto : goOutList) {
			switch (goOutDto.getTimesGoOut()) {
				case 1:
					vo.setLblPublicTime1(getTimeWaveFormat(goOutDto.getGoOutStart(), goOutDto.getGoOutEnd()));
					break;
				case 2:
					vo.setLblPublicTime2(getTimeWaveFormat(goOutDto.getGoOutStart(), goOutDto.getGoOutEnd()));
					break;
				default:
					break;
			}
		}
		// 私用外出情報取得
		goOutList = timeReference().goOut().getPrivateGoOutList(personalId, targetDate);
		// 私用外出情報設定
		for (GoOutDtoInterface goOutDto : goOutList) {
			switch (goOutDto.getTimesGoOut()) {
				case 1:
					vo.setLblPrivateTime1(getTimeWaveFormat(goOutDto.getGoOutStart(), goOutDto.getGoOutEnd()));
					break;
				case 2:
					vo.setLblPrivateTime2(getTimeWaveFormat(goOutDto.getGoOutStart(), goOutDto.getGoOutEnd()));
					break;
				default:
					break;
			}
		}
		// 勤怠データ修正情報取得
		AttendanceCorrectionDtoInterface correctionDto = timeReference().attendanceCorrection()
			.getLatestAttendanceCorrectionInfo(personalId, targetDate, TimeBean.TIMES_WORK_DEFAULT);
		if (correctionDto != null) {
			// 修正情報作成
			StringBuffer sb = new StringBuffer();
			sb.append(mospParams.getName("Corrector"));
			sb.append(mospParams.getName("Colon"));
			sb.append(reference().human().getHumanName(correctionDto.getCorrectionPersonalId(),
					correctionDto.getCorrectionDate()));
			sb.append(SEPARATOR);
			sb.append(mospParams.getName("Day"));
			sb.append(mospParams.getName("Hour"));
			sb.append(mospParams.getName("Colon"));
			sb.append(DateUtility.getStringDateAndDayAndTime(correctionDto.getCorrectionDate()));
			// 修正情報設定
			vo.setLblCorrectionHistory(sb.toString());
		}
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblAttendanceApprover(getWorkflowOperator(commentDto));
		vo.setLblAttendanceState(geWorkflowtStatus(commentDto));
		vo.setLblAttendanceComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * 勤怠申請以外の申請情報を取得し、設定する。<br>
	 * 但し、承認済みの申請のみを設定対象とする。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setOtherRequestValues() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 対象個人ID及び対象日取得
		String personalId = vo.getPersonalId();
		Date targetDate = vo.getTargetDate();
		// ワークフロー統合クラス準備
		WorkflowIntegrateBeanInterface workflowIntegrate = reference().workflowIntegrate();
		// 残業申請取得(勤務後残業)
		OvertimeRequestDtoInterface overtimeDto = timeReference().overtimeRequest().findForKeyOnWorkflow(personalId,
				targetDate, TimeConst.CODE_OVERTIME_WORK_AFTER);
		// 残業申請確認
		if (overtimeDto == null) {
			// 残業申請取得(勤務前残業)
			overtimeDto = timeReference().overtimeRequest().findForKeyOnWorkflow(personalId, targetDate,
					TimeConst.CODE_OVERTIME_WORK_BEFORE);
		}
		// 残業申請及びワークフロー状況確認
		if (overtimeDto != null && workflowIntegrate.isCompleted(overtimeDto.getWorkflow())) {
			// 残業申請情報設定
			setOvertimeValues(overtimeDto);
		}
		// 休暇申請取得
		List<HolidayRequestDtoInterface> holidayList = timeReference().holidayRequest().getHolidayRequestList(
				personalId, targetDate);
		// 休暇申請毎に処理
		for (HolidayRequestDtoInterface holidayDto : holidayList) {
			// 休暇申請及びワークフロー状況確認
			if (workflowIntegrate.isCompleted(holidayDto.getWorkflow())) {
				// 代休申請情報設定
				setHolidayValues(holidayDto);
				break;
			}
		}
		// 振出休出申請取得
		WorkOnHolidayRequestDtoInterface workOnHolidayDto = timeReference().workOnHolidayRequest()
			.findForKeyOnWorkflow(personalId, targetDate);
		// 振出休出申請及びワークフロー状況確認
		if (workOnHolidayDto != null && workflowIntegrate.isCompleted(workOnHolidayDto.getWorkflow())) {
			// 振出休出申請情報設定
			setWorkOnHolidayValues(workOnHolidayDto);
		}
		// 代休申請取得
		List<SubHolidayRequestDtoInterface> subHolidayList = timeReference().subHolidayRequest()
			.getSubHolidayRequestList(personalId, targetDate);
		// 代休申請毎に処理
		for (SubHolidayRequestDtoInterface subHolidayDto : subHolidayList) {
			// 代休申請及びワークフロー状況確認
			if (workflowIntegrate.isCompleted(subHolidayDto.getWorkflow())) {
				// 代休申請情報設定
				setSubHolidayValues(subHolidayDto);
				break;
			}
		}
		// 時差出勤申請取得
		DifferenceRequestDtoInterface differenceDto = timeReference().differenceRequest().findForKeyOnWorkflow(
				personalId, targetDate);
		// 時差出勤申請及びワークフロー状況確認
		if (differenceDto != null && workflowIntegrate.isCompleted(differenceDto.getWorkflow())) {
			// 振出休出申請情報設定
			setDifferenceValues(differenceDto);
		}
	}
	
	/**
	 * 残業申請情報を設定する。<br>
	 * @param dto 残業申請情報
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setOvertimeValues(OvertimeRequestDtoInterface dto) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 残業申請情報設定
		vo.setLblOverTimeType(getOvertimeTypeName(dto.getOvertimeType()));
		vo.setLblOverTimeSchedule(getTimeTimeFormat(dto.getRequestTime()));
		vo.setLblOverTimeReason(dto.getRequestReason());
		// 対象ワークフロー番号取得
		long workflow = dto.getWorkflow();
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblOverTimeApprover(getWorkflowOperator(commentDto));
		vo.setLblOverTimeState(geWorkflowtStatus(commentDto));
		vo.setLblOverTimeComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * 休暇申請情報を取得し、設定する。<br>
	 * @param dto 休暇申請情報
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setHolidayValues(HolidayRequestDtoInterface dto) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 休暇申請情報設定
		String holidayType = getHolidayTypeName(dto.getHolidayType1(), dto.getHolidayType2(), dto.getRequestStartDate());
		vo.setLblHolidayType(holidayType);
		vo.setLblHolidayLength(getHolidayRange(dto.getHolidayRange()));
		vo.setLblHolidayTime(getTimeWaveFormat(dto.getStartTime(), dto.getEndTime()));
		vo.setLblHolidayReason(dto.getRequestReason());
		// 対象ワークフロー番号取得
		long workflow = dto.getWorkflow();
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblHolidayApprover(getWorkflowOperator(commentDto));
		vo.setLblHolidayState(geWorkflowtStatus(commentDto));
		vo.setLblHolidayComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * 振出休出申請情報を取得し、設定する。<br>
	 * @param dto 振出休出申請情報
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setWorkOnHolidayValues(WorkOnHolidayRequestDtoInterface dto) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 対象ワークフロー番号取得
		long workflow = dto.getWorkflow();
		// 振出休出申請情報設定
		vo.setLblWorkOnHolidayDate(DateUtility.getStringDateAndDay(dto.getRequestDate()));
		vo.setLblWorkOnHolidayTime(getTimeWaveFormat(dto.getStartTime(), dto.getEndTime()));
		vo.setLblWorkOnHolidayReason(dto.getRequestReason());
		// 振替休日リスト取得
		List<SubstituteDtoInterface> substituteList = timeReference().substitute().getSubstituteList(workflow);
		if (substituteList.size() > 0) {
			// 振替休日情報設定
			vo.setLblWorkOnHolidayTransferDate(getStringDateAndDay(substituteList.get(0).getSubstituteDate()));
		}
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblWorkOnHolidayApprover(getWorkflowOperator(commentDto));
		vo.setLblWorkOnHolidayState(geWorkflowtStatus(commentDto));
		vo.setLblWorkOnHolidayComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * 代休申請情報を取得し、設定する。<br>
	 * @param dto 代休申請情報
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setSubHolidayValues(SubHolidayRequestDtoInterface dto) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 代休申請情報設定
		vo.setLblSubHolidayDate(getStringDateAndDay(dto.getRequestDate()));
		vo.setLblSubHolidayWorkDate(getStringDateAndDay(dto.getWorkDate()));
		// 対象ワークフロー番号取得
		long workflow = dto.getWorkflow();
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblSubHolidayApprover(getWorkflowOperator(commentDto));
		vo.setLblSubHolidayState(geWorkflowtStatus(commentDto));
		vo.setLblSubHolidayComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * 時差出勤申請情報を取得し、設定する。<br>
	 * @param dto 時差出勤申請情報
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setDifferenceValues(DifferenceRequestDtoInterface dto) throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// 時差出勤申請情報設定
		vo.setLblDifferenceDate(getStringDateAndDay(dto.getRequestDate()));
		vo.setLblDifferenceWorkType(getBeforeDifferenceRequestWorkTypeAbbr());
		vo.setLblDifferenceWorkTime(timeReference().differenceRequest().getDifferenceTime(dto));
		vo.setLblDifferenceReason(dto.getRequestReason());
		// 対象ワークフロー番号取得
		long workflow = dto.getWorkflow();
		// ワークフローコメント情報取得及び確認
		WorkflowCommentDtoInterface commentDto = reference().workflowComment().getLatestWorkflowCommentInfo(workflow);
		if (commentDto == null) {
			return;
		}
		// ワークフローコメント情報設定
		vo.setLblDifferenceApprover(getWorkflowOperator(commentDto));
		vo.setLblDifferenceState(geWorkflowtStatus(commentDto));
		vo.setLblDifferenceComment(commentDto.getWorkflowComment());
	}
	
	/**
	 * ボタン要否を設定する。<br>
	 * 申請確認詳細フラグ及びワークフロー情報で、判断する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setButtonFlag() throws MospException {
		// VO準備
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// ワークフロー統合クラス取得
		WorkflowIntegrateBeanInterface workflowIntegrate = reference().workflowIntegrate();
		// ワークフロー情報を取得
		WorkflowDtoInterface dto = reference().workflow().getLatestWorkflowInfo(vo.getWorkflow());
		// ログインユーザ個人ID取得
		String personalId = mospParams.getUser().getPersonalId();
		// 申請確認詳細フラグ及びワークフロー状況確認
		if (vo.isConfirmation()) {
			// ワークフロー状況確認(承認済)
			if (workflowIntegrate.isCompleted(dto) == false) {
				// 承認済でなければ承認解除ボタン不要
				vo.setNeedCancelButton(false);
				return;
			}
			// 対象個人IDにつき対象日付が未締であるかの確認
			if (timeReference().cutoffUtil().isNotTighten(vo.getPersonalId(), dto.getWorkflowDate()) == false) {
				// 未締でなければ承認解除ボタン不要
				vo.setNeedCancelButton(false);
				return;
			}
			// ログインユーザがスーパーユーザであるかを確認
			if (mospParams.getUserRole().isSuper()) {
				vo.setNeedCancelButton(true);
				return;
			}
			// ログインユーザが操作者(最終承認者)であるかを確認
			if (workflowIntegrate.isApprover(dto, personalId)) {
				vo.setNeedCancelButton(true);
				return;
			}
			vo.setNeedCancelButton(false);
		} else {
			// ワークフロー承認可否確認(承認可能)
			if (workflowIntegrate.isApprovable(dto) == false) {
				// 承認可能でなければ承認差戻ボタン不要
				vo.setNeedApproveButton(false);
				return;
			}
			// 対象個人IDにつき対象日付が未締であるかの確認
			if (timeReference().cutoffUtil().isNotTighten(vo.getPersonalId(), dto.getWorkflowDate()) == false) {
				// 未締でなければ承認差戻ボタン不要
				vo.setNeedApproveButton(false);
				return;
			}
			// ログインユーザがスーパーユーザであるかを確認
			if (mospParams.getUserRole().isSuper()) {
				vo.setNeedApproveButton(true);
				return;
			}
			// ログインユーザが操作者であるかを確認
			if (workflowIntegrate.isApprover(dto, personalId)) {
				vo.setNeedApproveButton(true);
				return;
			}
			// システム日付における代理情報を取得
			List<SubApproverDtoInterface> subApproverList = reference().subApprover().findForSubApproverId(personalId,
					PlatformConst.WORKFLOW_TYPE_TIME, getSystemDate(), getSystemDate());
			// 代理情報毎に処理
			for (SubApproverDtoInterface subApproverDto : subApproverList) {
				// 代理元が操作者であるかを確認
				if (workflowIntegrate.isApprover(dto, subApproverDto.getPersonalId())) {
					vo.setNeedApproveButton(true);
					return;
				}
			}
			vo.setNeedApproveButton(false);
		}
	}
	
	/**
	 * VOからワークフローコメントを取得する。<br>
	 * @return ワークフローコメント
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected String getWorkflowComment() throws MospException {
		// VO取得
		ApprovalCardVo vo = (ApprovalCardVo)mospParams.getVo();
		// ワークフローコメント準備
		String workflowComment = null;
		// ワークフローコメント取得
		if (vo.isAttendance()) {
			workflowComment = vo.getTxtAttendanceComment();
		} else if (vo.isOvertime()) {
			workflowComment = vo.getTxtOverTimeComment();
		} else if (vo.isHoliday()) {
			workflowComment = vo.getTxtHolidayComment();
		} else if (vo.isWorkOnHoliday()) {
			workflowComment = vo.getTxtWorkOnHolidayComment();
		} else if (vo.isSubHoliday()) {
			workflowComment = vo.getTxtCompensationComment();
		} else if (vo.isDifference()) {
			workflowComment = vo.getTxtDifferenceComment();
		}
		return workflowComment;
	}
	
	/**
	 * 勤務形態名称【HH:MM～HH:MM】を取得する。
	 * 勤怠情報がなければ空文字を返す。
	 * @param dto 勤怠情報
	 * @return 勤務形態(名称【HH:MM～HH:MM】)
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected String getWorkTypeAbbrStartTimeEndTime(AttendanceDtoInterface dto) throws MospException {
		// 勤怠情報確認
		if (dto == null) {
			return "";
		}
		// 勤務形態取得
		String workTypeCode = dto.getWorkTypeCode();
		// 時差出勤の場合
		if (isDifferenceWorkType(workTypeCode)) {
			return mospParams.getProperties().getCodeItemName(TimeConst.CODE_DIFFERENCE_TYPE, dto.getWorkTypeCode());
		}
		// 法定休日労動の場合
		if (TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(workTypeCode)) {
			return mospParams.getName("Legal") + mospParams.getName("WorkingHoliday");
		}
		// 所定休日労動の場合
		if (TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
			return mospParams.getName("Prescribed") + mospParams.getName("WorkingHoliday");
		}
		// 勤務形態略称を取得
		return timeReference().workType().getWorkTypeAbbrAndTime(workTypeCode, dto.getWorkDate());
	}
	
	/**
	 * 時差出勤の勤務形態コードであるか確認する。
	 * @param workTypeCode 勤務形態コード
	 * @return 確認結果(true：時差出勤の勤務形態コード、false：時差出勤ではない勤務形態コード)
	 */
	protected boolean isDifferenceWorkType(String workTypeCode) {
		return TimeConst.CODE_DIFFERENCE_TYPE_A.equals(workTypeCode)
				|| TimeConst.CODE_DIFFERENCE_TYPE_B.equals(workTypeCode)
				|| TimeConst.CODE_DIFFERENCE_TYPE_C.equals(workTypeCode)
				|| TimeConst.CODE_DIFFERENCE_TYPE_D.equals(workTypeCode)
				|| TimeConst.CODE_DIFFERENCE_TYPE_S.equals(workTypeCode);
	}
	
	/**
	 * ワークフロー操作者名を取得する。<br>
	 * @param dto ワークフローコメント情報
	 * @return ワークフロー操作者名
	 * @throws MospException 操作者名の取得に失敗した場合
	 */
	protected String getWorkflowOperator(WorkflowCommentDtoInterface dto) throws MospException {
		return reference().human().getHumanName(dto.getPersonalId(), dto.getWorkflowDate());
	}
	
	/**
	 * ワークフロー状況を取得する。<br>
	 * @param dto ワークフローコメント情報
	 * @return ワークフロー状況
	 */
	protected String geWorkflowtStatus(WorkflowCommentDtoInterface dto) {
		return getStatusStageValueView(dto.getWorkflowStatus(), dto.getWorkflowStage());
	}
	
	/**
	 * 申請確認詳細名称を取得する。<br>
	 * @return 申請確認詳細
	 */
	protected String getNameRequestCard() {
		return mospParams.getName("RequestCardVo");
	}
	
}
