/*
 * 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 General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.kintai.common.part;

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

import jp.mosp.common.CommonConst;
import jp.mosp.common.dto.KintaiCommonDtoInterface;
import jp.mosp.common.part.PartInfo;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.TimeUtil;
import jp.mosp.common.utils.VariousUtil;
import jp.mosp.kintai.workflow.dao.KtHolidayRequestDao;
import jp.mosp.kintai.workflow.dto.KtHolidayRequestDto;

/**
 * 休暇申請に関するPart
 * @author yoshida
 *	@version	0.0.1
 */
public class HolidayRequestPart extends KintaiBasePart {
	
	/**
	 * コンストラクタ
	 */
	public HolidayRequestPart() {
		super();
	}
	
	/**
	 * コンストラクタ
	 * @param partInfo Partを利用する際に必要な情報
	 */
	public HolidayRequestPart(PartInfo partInfo) {
		super(partInfo);
	}
	

	/**
	 * KtHolidayRequestDaoインスタンス
	 */
	private KtHolidayRequestDao	holidayRequestDao;
	

	/**
	 * 休暇申請テーブルDAOの取得
	 * @return	初期化済みKtHolidayRequestDaoインスタンス
	 * @throws Exception	例外処理が発生した場合
	 */
	public KtHolidayRequestDao getKtHolidayRequestDao() throws Exception {
		if (VariousUtil.isNull(holidayRequestDao)) {
			holidayRequestDao = (KtHolidayRequestDao)getPreparedDao(KtHolidayRequestDao.class.getCanonicalName());
		}
		return holidayRequestDao;
	}
	
	/**
	 * 休暇申請情報取得
	 * @param voucher	対象伝票番号
	 * @return	検索結果(DTO)
	 * @throws Exception	例外処理が発生した場合
	 */
	public KtHolidayRequestDto getHolidayRequest(int voucher) throws Exception {
		return getKtHolidayRequestDao().findForKey(voucher);
	}
	
	/**
	 * 休暇申請情報取得
	 * @param kCode				対象社員コード
	 * @param targetDate		対象年月日
	 * @return	検索結果(DTO)
	 * @throws Exception	例外処理が発生した場合
	 */
	public KtHolidayRequestDto getHolidayRequest(String kCode, Date targetDate) throws Exception {
		return getKtHolidayRequestDao().findForHolidayDate(kCode, targetDate);
	}
	
	/**
	 * 休暇申請情報有無判断
	 * @param kCode				対象社員コード
	 * @param targetDate		対象年月日
	 * @return	休暇申請がある場合true、そうでない場合false
	 * @throws Exception	例外処理が発生した場合
	 */
	public boolean existHolidayRequest(String kCode, Date targetDate) throws Exception {
		return VariousUtil.isNotNull(getHolidayRequest(kCode, targetDate));
	}
	
	/**
	 * 有給休暇（全休）区分配列取得
	 * @return	有給休暇（全休）区分配列
	 */
	public static String[] getPaidHolidayAllArray() {
		return new String[]{ CommonConst.CODE_HOLIDAY_ALL, CommonConst.NAM_VACATION_LEAVE_ALL };
	}
	
	/**
	 * 有給休暇（前半休）区分配列取得
	 * @return	有給休暇（前半休）区分配列
	 */
	public static String[] getPaidHolidayStartArray() {
		return new String[]{ CommonConst.CODE_HOLIDAY_HALF_START, CommonConst.NAM_HOLIDAY_HALF_START };
	}
	
	/**
	 * 有給休暇（後半休）区分配列取得
	 * @return	有給休暇（後半休）区分配列
	 */
	public static String[] getPaidHolidayQuitArray() {
		return new String[]{ CommonConst.CODE_HOLIDAY_HALF_QUIT, CommonConst.NAM_HOLIDAY_HALF_QUIT };
	}
	
	/**
	 * 有給休暇（時間休）区分配列取得
	 * @return	有給休暇（時間休）区分配列
	 */
	public static String[] getPaidHolidayTimeArray() {
		return new String[]{ CommonConst.CODE_PAID_HOLIDAY_TIME, CommonConst.NAM_PAID_HOLIDAY_TIME };
	}
	
	/**
	 * 有給休暇全区分配列取得
	 * @return	有給休暇区分配列
	 */
	public static String[][] getHolidayRequestTypeArrayAll() {
		return new String[][]{ getPaidHolidayAllArray(), getPaidHolidayStartArray(), getPaidHolidayQuitArray(),
			getPaidHolidayTimeArray(), };
	}
	
	/**
	 * 有給休暇区分配列取得
	 * @return	有給休暇区分配列
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[][] getHolidayRequestTypeArray() throws Exception {
		String[][] aryType = new String[][]{ getPaidHolidayAllArray(), getPaidHolidayStartArray(),
			getPaidHolidayQuitArray() };
		if (part().mospcode().useHourPaidHolidayFunction()) {
			return getHolidayRequestTypeArrayAll();
		}
		return aryType;
	}
	
	/**
	 * 休暇理由名称取得（有給休暇区分を含む）
	 * @param dto	対象DTO
	 * @param addTime		時間帯表示判断
	 * @return	休暇理由名称
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getReasonNameWithType(KtHolidayRequestDto dto, boolean addTime) throws Exception {
		StringBuffer sb = new StringBuffer();
		if (VariousUtil.isNotNull(dto)) {
			// 休暇理由
			sb.append(part().mospcode().getHolidayName(dto.getReason()));
			// 有給休暇の場合
			if (isPaidHoliday(dto)) {
				// 時間休の場合
				if (isPaidHolidayTime(dto.getHolidayType()) && addTime) {
					sb.append(StringUtil.surroundRoundBracket(new StringBuffer().append(
							TimeUtil.convIntegerTimeToStringTime(dto.getStartTime())).append(CommonConst.STR_TERM)
						.append(TimeUtil.convIntegerTimeToStringTime(dto.getEndTime())).toString()));
				} else {
					sb.append(StringUtil.surroundRoundBracket(getHolidayTypeName(dto.getHolidayType())));
				}
			} else if (isSubHoliday(dto)) {
				sb.append(StringUtil.surroundRoundBracket(getHolidayTypeName(dto.getHolidayType())));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 休暇種類名称取得
	 * @param holidayType 対象休暇種類コード
	 * @return 休暇種類名称
	 */
	public static String getHolidayTypeName(String holidayType) {
		String typeName = "";
		if (isAllHolidayType(holidayType)) {
			typeName = CommonConst.NAM_VACATION_LEAVE_ALL;
		} else if (isStartHalfHolidayType(holidayType)) {
			typeName = CommonConst.NAM_HOLIDAY_HALF_START;
		} else if (isQuitHalfHolidayType(holidayType)) {
			typeName = CommonConst.NAM_HOLIDAY_HALF_QUIT;
		} else if (isPaidHolidayTime(holidayType)) {
			typeName = CommonConst.NAM_PAID_HOLIDAY_TIME;
		}
		return typeName;
	}
	
	/**
	 * 有給休暇申請判断
	 * @param reason	対象休暇理由コード
	 * @return
	 * <p>
	 * 有給休暇の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHoliday(String reason) {
		return PaidHolidayPart.isPaidHoliday(reason);
	}
	
	/**
	 * 全休判断。
	 * @param holidayType 	対象休暇種類コード
	 * @return
	 * <p>
	 * 全休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isAllHolidayType(String holidayType) {
		return CommonConst.CODE_HOLIDAY_ALL.equals(holidayType);
	}
	
	/**
	 * 全休判断。
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 全休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isAllHolidayType(KtHolidayRequestDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return isAllHolidayType(dto.getHolidayType());
		}
		return false;
	}
	
	/**
	 * 前半休判断。
	 * @param holidayType 	対象休暇種類コード
	 * @return
	 * <p>
	 * 前半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isStartHalfHolidayType(String holidayType) {
		return CommonConst.CODE_HOLIDAY_HALF_START.equals(holidayType);
	}
	
	/**
	 * 前半休判断。
	 * @param dto  対象DTO
	 * @return
	 * <p>
	 * 前半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isStartHalfHolidayType(KtHolidayRequestDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return isStartHalfHolidayType(dto.getHolidayType());
		}
		return false;
	}
	
	/**
	 * 後半休判断。
	 * @param holidayType 	対象休暇種類コード
	 * @return
	 * <p>
	 * 後半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isQuitHalfHolidayType(String holidayType) {
		return CommonConst.CODE_HOLIDAY_HALF_QUIT.equals(holidayType);
	}
	
	/**
	 * 後半休判断。
	 * @param dto  対象DTO
	 * @return
	 * <p>
	 * 後半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isQuitHalfHolidayType(KtHolidayRequestDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return isQuitHalfHolidayType(dto.getHolidayType());
		}
		return false;
	}
	
	/**
	 * 半休判断。
	 * @param holidayType 	対象休暇種類コード
	 * @return
	 * <p>
	 * 前半休、後半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isHalfHolidayType(String holidayType) {
		return isStartHalfHolidayType(holidayType) || isQuitHalfHolidayType(holidayType);
	}
	
	/**
	 * 半休判断。
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 前半休、後半休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isHalfHolidayType(KtHolidayRequestDto dto) {
		return isStartHalfHolidayType(dto) || isQuitHalfHolidayType(dto);
	}
	
	/**
	 * 有給休暇申請判断
	 * @param dto		対象DTO
	 * @return
	 * <p>
	 * 有給休暇の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHoliday(KtHolidayRequestDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return isPaidHoliday(dto.getReason());
		}
		return false;
	}
	
	/**
	 * 有給休暇（全休）申請判断
	 * @param dto		対象DTO
	 * @return
	 * <p>
	 * 有給休暇（全休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayAll(KtHolidayRequestDto dto) {
		return isPaidHoliday(dto) && isAllHolidayType(dto);
	}
	
	/**
	 * 有給休暇（前半休）申請判断
	 * @param dto		対象DTO
	 * @return
	 * <p>
	 * 有給休暇（前半休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayStart(KtHolidayRequestDto dto) {
		return isPaidHoliday(dto) && isStartHalfHolidayType(dto);
	}
	
	/**
	 * 有給休暇（後半休）申請判断
	 * @param dto		対象DTO
	 * @return
	 * <p>
	 * 有給休暇（後半休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayQuit(KtHolidayRequestDto dto) {
		return isPaidHoliday(dto) && isQuitHalfHolidayType(dto);
	}
	
	/**
	 * 有給休暇半休申請判断
	 * @param dto 	対象DTO
	 * @return
	 * <p>
	 * 有給休暇申請が前半休または後半休の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayHalf(KtHolidayRequestDto dto) {
		return isPaidHolidayStart(dto) || isPaidHolidayQuit(dto);
	}
	
	/**
	 * 有給休暇（時間休）申請判断
	 * @param holidayType		対象休暇種類コード
	 * @return
	 * <p>
	 * 有給休暇（時間休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayTime(String holidayType) {
		return CommonConst.CODE_PAID_HOLIDAY_TIME.equals(holidayType);
	}
	
	/**
	 * 有給休暇（時間休）申請判断
	 * @param dto		対象DTO
	 * @return
	 * <p>
	 * 有給休暇（時間休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isPaidHolidayTime(KtHolidayRequestDto dto) {
		return isPaidHoliday(dto) && isPaidHolidayTime(dto.getHolidayType());
	}
	
	/**
	 * 有給休暇時間取得
	 * @param dto		対象DTO
	 * @return	有給休暇時間(時)
	 */
	public static int getHolidayTime(KtHolidayRequestDto dto) {
		if (isPaidHolidayTime(dto)) {
			return Double.valueOf(TimeUtil.convMinutesToDoubleHour(dto.getEndTime() - dto.getStartTime())).intValue();
		}
		return 0;
	}
	
	/**
	 * 二次承認済み判断
	 * @param dto	対象DTO
	 * @return	休暇申請が二次承認済みの場合true、そうでない場合false
	 * @throws Exception 	例外処理が発生した場合
	 */
	public boolean isStatus2ndApproved(KtHolidayRequestDto dto) throws Exception {
		return part().workflow().isStatusLastApproved(dto.getWorkflow());
	}
	
	/**
	 * 指定期間中の休暇申請一覧
	 * @param kCode 社員コード
	 * @param startDate 開始年月日
	 * @param endDate 終了年月日
	 * @return 休暇申請リスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getHolidayRequestList(String kCode, Date startDate, Date endDate) throws Exception {
		return getKtHolidayRequestDao().findForCondition(kCode, startDate, endDate);
	}
	
	/**
	 * 指定期間中の承認済み休暇申請一覧
	 * @param kCode 社員コード
	 * @param startDate 開始年月日
	 * @param endDate 終了年月日
	 * @return  休暇申請リスト
	 * @throws Exception 	例外処理が発生した場合
	 * 
	 */
	public List<KtHolidayRequestDto> getApprovedHolidayRequestList(String kCode, Date startDate, Date endDate)
			throws Exception {
		return getKtHolidayRequestDao().findForCondition(kCode, startDate, endDate, CommonConst.NUM_LAST_LAYER,
				WorkflowPart.getStatusCodeArray()[1]);
	}
	
	/**
	 * 指定期間中の承認済みの有給休暇申請一覧
	 * @param kCode 社員コード
	 * @param startDate 開始年月日
	 * @param endDate 終了年月日
	 * @return 休暇申請リスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getApprovedPaidHolidayRequestList(String kCode, Date startDate, Date endDate)
			throws Exception {
		return getKtHolidayRequestDao().findForCondition(kCode, CommonConst.CODE_HOLIDAY_REASON_PAID, startDate,
				endDate, CommonConst.NUM_LAST_LAYER, WorkflowPart.getStatusCodeArray()[1]);
	}
	
	/**
	 * 月60時間の時間外による代休申請判断
	 * @param reason 	対象休暇理由コード
	 * @return
	 * <p>
	 * 月60時間の時間外による代休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHoliday(String reason) {
		return CommonConst.CODE_SUB_HOLIDAY_REQUEST.equals(reason);
	}
	
	/**
	 * 月60時間の時間外による代休申請判断
	 * @param dto 	対象DTO
	 * @return
	 * <p>
	 * 月60時間の時間外による代休申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHoliday(KtHolidayRequestDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return isSubHoliday(dto.getReason());
		}
		return false;
	}
	
	/**
	 * 月60時間時間外による代休（全休）申請判断。
	 * @param dto 対象DTO
	 * @return 
	 * <p>
	 * 月60時間の時間外による代休（全休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHolidayAll(KtHolidayRequestDto dto) {
		return isSubHoliday(dto) && isAllHolidayType(dto);
	}
	
	/**
	 * 月60時間時間外による代休（前半休）申請判断。
	 * @param dto 対象DTO
	 * @return 
	 * <p>
	 * 月60時間の時間外による代休（前半休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHolidayStartHalf(KtHolidayRequestDto dto) {
		return isSubHoliday(dto) && isStartHalfHolidayType(dto);
	}
	
	/**
	 * 月60時間時間外による代休（後半休）申請判断。
	 * @param dto 対象DTO
	 * @return 
	 * <p>
	 * 月60時間の時間外による代休（後半休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHolidayQuitHalf(KtHolidayRequestDto dto) {
		return isSubHoliday(dto) && isQuitHalfHolidayType(dto);
	}
	
	/**
	 * 月60時間時間外による代休（半休）申請判断。
	 * @param dto 対象DTO
	 * @return 
	 * <p>
	 * 月60時間の時間外による代休（半休）申請の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isSubHolidayHalf(KtHolidayRequestDto dto) {
		return isSubHoliday(dto) && isHalfHolidayType(dto);
	}
	
	/**
	 * 社員対象年月日の休暇申請一覧取得。
	 * @param kCode 対象社員コード
	 * @param targetDate 対象年月日
	 * @return 対象年月日の休暇申請一覧
	 * @throws Exception 	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getDateRequestList(String kCode, Date targetDate) throws Exception {
		return getDateRequestListForReason(kCode, targetDate, "");
	}
	
	/**
	 * 社員対象年月日の対象休暇理由休暇申請一覧取得。
	 * @param kCode 対象社員コード
	 * @param targetDate 対象年月日
	 * @param reason 対象休暇理由コード
	 * @return 対象年月日の対象休暇理由休暇申請一覧
	 * @throws Exception  	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getDateRequestListForReason(String kCode, Date targetDate, String reason)
			throws Exception {
		return getDateRequestListForReasonType(kCode, targetDate, reason, "");
	}
	
	/**
	 * 社員対象年月日の対象休暇理由、休暇種類休暇申請一覧取得。
	 * @param kCode 対象社員コード
	 * @param targetDate 対象年月日
	 * @param reason 対象休暇理由
	 * @param holidayType 対象休暇種類コード
	 * @return 対象年月日の対象休暇理由、休暇種類休暇申請一覧
	 * @throws Exception  	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getDateRequestListForReasonType(String kCode, Date targetDate, String reason,
			String holidayType) throws Exception {
		return getKtHolidayRequestDao().findForCondition(kCode, reason, holidayType, targetDate);
	}
	
	/**
	 * 社員対象年月日の対象休暇理由、休暇種類、承認状況休暇申請一覧取得。
	 * @param kCode 対象社員コード
	 * @param targetDate 対象年月日
	 * @param reason 対象休暇理由
	 * @param holidayType 対象休暇種類コード
	 * @param layer 承認階層
	 * @param status 承認状況
	 * @return 	社員対象年月日の対象休暇理由、休暇種類、承認状況休暇申請一覧
	 * @throws Exception  	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getDateRequestList(String kCode, Date targetDate, String reason,
			String holidayType, int layer, String status) throws Exception {
		return getKtHolidayRequestDao().findForCondition(kCode, targetDate, targetDate, reason, holidayType, layer,
				status);
	}
	
	/**
	 * 休暇申請の内容を反映する。
	 * @param dto 対象DTO
	 * @throws Exception  	例外処理が発生した場合
	 */
	public void margeHolidayRequest(KintaiCommonDtoInterface dto) throws Exception {
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			// 月60時間時間外時間機能
			boolean useSubHolidayFunction = part().mospcode().useSubstituteHolidayFunction();
			// 休暇時間
			int totalHolidayTime = 0;
			// 時間単位年休件数
			int unitHourHoliday = 0;
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済みのみ
				if (part().holidayRequest().isStatus2ndApproved(requestDto)) {
					// 勤務可能
					if (KintaiCommonPart.isAvailableWorkType(dto)) {
						int holidayTime = 0;
						int workTime = dto.getKinmuJi();
						// 午前半休
						if (isPaidHolidayStart(requestDto)) {
							dto.setSHankyuKb(CommonConst.NUM_START_HALF_HOLIDAY_FLAG_ON);
						}
						// 午後半休
						if (isPaidHolidayQuit(requestDto)) {
							dto.setTHankyuKb(CommonConst.NUM_QUIT_HALF_HOLIDAY_FLAG_ON);
						}
						// 月60時間時間外による代休（前半休）
						if (isSubHolidayStartHalf(requestDto) && useSubHolidayFunction) {
							dto.setSHankyuKb(CommonConst.CODE_SUB_HOLIDAY_HALF_FLAG);
						}
						// 月60時間時間外による代休（後半休）
						if (isSubHolidayQuitHalf(requestDto) && useSubHolidayFunction) {
							dto.setTHankyuKb(CommonConst.CODE_SUB_HOLIDAY_HALF_FLAG);
						}
						// マージ
						if (StringUtil.isNotNull(dto.getTaJikoku())) {
							part().kintai().runCalculatedInfo(dto);
						} else {
							part().kintai().runStartCalculate(dto);
						}
						// 時間単位年休対応
						if (HolidayRequestPart.isPaidHolidayTime(requestDto)) {
							holidayTime = TimeUtil.convHourToMinutes(HolidayRequestPart.getHolidayTime(requestDto));
							totalHolidayTime += holidayTime;
							workTime -= holidayTime;
							// 時間単位年休件数加算
							unitHourHoliday++;
							dto.setNijiKyu(unitHourHoliday);
						}
						if (workTime < 0) {
							workTime = 0;
						}
						dto.setKinmuJi(workTime);
						dto.setKKJikan(totalHolidayTime);
						// 申請状況へ変更
						if (StringUtil.isNotNull(dto.getTaJikoku())) {
							dto.setSnRiyuu(CommonConst.NUM_ATTENDANCE_REQUEST);
						}
					} else {
						// 全休
						// 内容を初期化
						KintaiCommonPart.initKintaiInfo(dto);
						// 有休申請
						if (isPaidHolidayAll(requestDto)) {
							dto.setKinmu(CommonConst.ATTENDANCE_TYPE_HOLIDAY);
							dto.setKKRiyuu(CommonConst.CODE_HOLIDAY_REASON_PAID);
						} else if (isSubHolidayAll(requestDto) && useSubHolidayFunction) {
							// 月60時間時間外による代休
							dto.setKinmu(CommonConst.ATTENDANCE_TYPE_HOLIDAY);
							dto.setKKRiyuu(CommonConst.CODE_SUB_HOLIDAY_REQUEST);
						} else {
							dto.setKinmu(CommonConst.ATTENDANCE_TYPE_HOLIDAY);
							dto.setKKRiyuu(requestDto.getReason());
						}
						// 申請状況へ変更
						dto.setSnRiyuu(CommonConst.NUM_ATTENDANCE_REQUEST);
					}
				}
			}
		}
	}
	
	/**
	 * 表示用対象休暇一覧（承認状況追加）
	 * @param holidayList 対象休暇理由一覧
	 * @return
	 * 表示用対象休暇一覧（承認状況追加）配列
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[] getLabelHolidayRequestStatusArray(List<KtHolidayRequestDto> holidayList) throws Exception {
		List<String> labelList = new ArrayList<String>();
		for (KtHolidayRequestDto dto : holidayList) {
			StringBuffer sb = new StringBuffer();
			String statusCode = part().workflow().toKintaiApprovalStatus(dto.getWorkflow());
			// 下書き以外
			if (!KintaiApprovalPart.isDraft(statusCode)) {
				// 休暇理由
				sb.append(part().holidayRequest().getReasonNameWithType(dto, true));
				// 承認状況
				sb.append(StringUtil.surroundBracket(part().kintaiApproval().getApprovalName(statusCode)));
			}
			if (sb.length() != 0) {
				labelList.add(sb.toString());
			}
		}
		return StringUtil.listToArray(labelList);
	}
	
	/**
	 * 対象発生年月の承認済み時間外代休休暇申請一覧取得
	 * @param kCode 対象社員コード
	 * @param occurYear 発生年
	 * @param occurMonth 発生月
	 * @return 対象発生年月の承認済み時間外代休休暇申請一覧
	 * @throws Exception 	例外処理が発生した場合
	 */
	public List<KtHolidayRequestDto> getOccurYearMonthList(String kCode, int occurYear, int occurMonth)
			throws Exception {
		return getKtHolidayRequestDao().findForOccur(kCode, CommonConst.CODE_SUB_HOLIDAY_REQUEST,
				StringUtil.combineByHyphen(String.valueOf(occurYear), String.valueOf(occurMonth)),
				CommonConst.NUM_LAST_LAYER, WorkflowPart.getStatusCodeArray()[1]);
	}
	
	/**
	 * 発生年月利用時間取得
	 * @param dto 対象DTO
	 * @param occurYear 発生年
	 * @param occurMonth 発生月
	 * @return 発生年月利用時間
	 */
	public static int getOccurUseTime(KtHolidayRequestDto dto, int occurYear, int occurMonth) {
		if (isSubHoliday(dto)) {
			String occurYearMonth = StringUtil.combineByHyphen(String.valueOf(occurYear), String.valueOf(occurMonth));
			if (dto.getOccurDate1().equals(occurYearMonth)) {
				return dto.getUseTime1();
			} else if (dto.getOccurDate2().equals(occurYearMonth)) {
				return dto.getUseTime2();
			}
		}
		return 0;
	}
	
	/**
	 * 対象の休暇申請を含む場合リストから削除する。
	 * @param dto 対象DTO
	 * @param list 対象リスト
	 */
	public static void removeSameRequest(KtHolidayRequestDto dto, List<KtHolidayRequestDto> list) {
		if (VariousUtil.isNotNull(dto) && VariousUtil.isNotNull(list)) {
			KtHolidayRequestDto targetDto = null;
			for (KtHolidayRequestDto requestDto : list) {
				if (requestDto.getVoucher() == dto.getVoucher()) {
					targetDto = requestDto;
				}
			}
			if (VariousUtil.isNotNull(targetDto)) {
				list.remove(targetDto);
			}
		}
	}
	
	/**
	 * 有給休暇申請承認済判断(全休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の有給休暇申請(全休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedPaidHolidayRequestAll(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (KintaiCommonPart.isAllHoliday(dto) && isPaidHolidayAll(requestDto)) {
						// 有給休暇
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
	/**
	 * 有給休暇申請承認済判断(午前半休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の有給休暇申請(午前半休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedPaidHolidayRequestStartHalf(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (KintaiCommonPart.isStartHalfHoliday(dto) && isPaidHolidayStart(requestDto)) {
						// 有給休暇(午前半休)
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
	/**
	 * 有給休暇申請承認済判断(午後半休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の有給休暇申請(午後半休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedPaidHolidayRequestQuitHalf(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (KintaiCommonPart.isQuitHalfHoliday(dto) && isPaidHolidayQuit(requestDto)) {
						// 有給休暇(午後半休)
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
	/**
	 * 代替休暇申請承認済判断(全休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の代替休暇申請(全休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedSubstituteHolidayRequestAll(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (part().mospcode().useSubstituteHolidayFunction() && KintaiCommonPart.isSubstituteAll(dto)
							&& isSubHolidayAll(requestDto)) {
						// 月60時間時間外による代休
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
	/**
	 * 代替休暇申請承認済判断(午前半休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の代替休暇申請(午前半休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedSubstituteHolidayRequestStartHalf(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (part().mospcode().useSubstituteHolidayFunction()
							&& KintaiCommonPart.isOverTimeSubHolidayStart(dto) && isSubHolidayStartHalf(requestDto)) {
						// 月60時間時間外による代休(午前半休)
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
	/**
	 * 代替休暇申請承認済判断(午後半休)
	 * @param dto 対象DTO
	 * @return
	 * <p>
	 * 対象年月日の代替休暇申請(午後半休)が二次承認済の場合true、そうでない場合false。
	 * </p>
	 * @throws Exception 例外処理が発生した場合
	 */
	public boolean isApprovedSubstituteHolidayRequestQuitHalf(KintaiCommonDtoInterface dto) throws Exception {
		boolean approved = false;
		if (VariousUtil.isNotNull(dto)) {
			// 休暇申請を取得
			List<KtHolidayRequestDto> list = getDateRequestList(dto.getKCode(), DateUtil.convStringDateToDate(dto
				.getHizuke()));
			for (KtHolidayRequestDto requestDto : list) {
				// 二次承認済
				if (isStatus2ndApproved(requestDto)) {
					if (part().mospcode().useSubstituteHolidayFunction()
							&& KintaiCommonPart.isOverTimeSubHolidayQuit(dto) && isSubHolidayQuitHalf(requestDto)) {
						// 月60時間時間外による代休(午後半休)
						approved = true;
					}
					break;
				}
			}
		}
		return approved;
	}
	
}
