/*
 * 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.HashMap;
import java.util.List;
import java.util.Map;

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.constant.PlatformConst;
import jp.mosp.platform.dao.human.EntranceDaoInterface;
import jp.mosp.platform.dao.human.HumanDaoInterface;
import jp.mosp.platform.dao.human.RetirementDaoInterface;
import jp.mosp.platform.dao.workflow.WorkflowDaoInterface;
import jp.mosp.platform.dto.human.EntranceDtoInterface;
import jp.mosp.platform.dto.human.HumanDtoInterface;
import jp.mosp.platform.dto.human.RetirementDtoInterface;
import jp.mosp.platform.dto.workflow.WorkflowDtoInterface;
import jp.mosp.time.base.TimeApplicationBean;
import jp.mosp.time.bean.CutoffUtilBeanInterface;
import jp.mosp.time.bean.ScheduleDateReferenceBeanInterface;
import jp.mosp.time.bean.ScheduleReferenceBeanInterface;
import jp.mosp.time.bean.TotalTimeCalcBeanInterface;
import jp.mosp.time.constant.TimeConst;
import jp.mosp.time.dao.settings.AllowanceDaoInterface;
import jp.mosp.time.dao.settings.AttendanceDaoInterface;
import jp.mosp.time.dao.settings.DifferenceRequestDaoInterface;
import jp.mosp.time.dao.settings.HolidayDaoInterface;
import jp.mosp.time.dao.settings.HolidayRequestDaoInterface;
import jp.mosp.time.dao.settings.OvertimeRequestDaoInterface;
import jp.mosp.time.dao.settings.ScheduleDaoInterface;
import jp.mosp.time.dao.settings.ScheduleDateDaoInterface;
import jp.mosp.time.dao.settings.SubHolidayDaoInterface;
import jp.mosp.time.dao.settings.SubHolidayRequestDaoInterface;
import jp.mosp.time.dao.settings.SubstituteDaoInterface;
import jp.mosp.time.dao.settings.TimeSettingDaoInterface;
import jp.mosp.time.dao.settings.TotalAbsenceDaoInterface;
import jp.mosp.time.dao.settings.TotalAllowanceDaoInterface;
import jp.mosp.time.dao.settings.TotalLeaveDaoInterface;
import jp.mosp.time.dao.settings.TotalOtherVacationDaoInterface;
import jp.mosp.time.dao.settings.WorkOnHolidayRequestDaoInterface;
import jp.mosp.time.dto.settings.AllowanceDtoInterface;
import jp.mosp.time.dto.settings.ApplicationDtoInterface;
import jp.mosp.time.dto.settings.AttendanceDtoInterface;
import jp.mosp.time.dto.settings.CutoffDtoInterface;
import jp.mosp.time.dto.settings.CutoffErrorListDtoInterface;
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.OvertimeRequestDtoInterface;
import jp.mosp.time.dto.settings.ScheduleDateDtoInterface;
import jp.mosp.time.dto.settings.ScheduleDtoInterface;
import jp.mosp.time.dto.settings.SubHolidayDtoInterface;
import jp.mosp.time.dto.settings.SubHolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.SubstituteDtoInterface;
import jp.mosp.time.dto.settings.TimeSettingDtoInterface;
import jp.mosp.time.dto.settings.TotalAbsenceDtoInterface;
import jp.mosp.time.dto.settings.TotalAllowanceDtoInterface;
import jp.mosp.time.dto.settings.TotalLeaveDtoInterface;
import jp.mosp.time.dto.settings.TotalOtherVacationDtoInterface;
import jp.mosp.time.dto.settings.TotalTimeDataDtoInterface;
import jp.mosp.time.dto.settings.WorkOnHolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.impl.CutoffErrorListDto;
import jp.mosp.time.dto.settings.impl.TmdTotalAbsenceDto;
import jp.mosp.time.dto.settings.impl.TmdTotalAllowanceDto;
import jp.mosp.time.dto.settings.impl.TmdTotalLeaveDto;
import jp.mosp.time.dto.settings.impl.TmdTotalOtherVacationDto;
import jp.mosp.time.utils.TimeUtility;

/**
 * 勤怠集計クラス。
 */
public class TotalTimeCalcBean extends TimeApplicationBean implements TotalTimeCalcBeanInterface {
	
	/**
	 * 人事マスタDAOクラス。<br>
	 */
	HumanDaoInterface									humanDao;
	
	/**
	 * 入社情報DAOクラス。<br>
	 */
	EntranceDaoInterface								entranceDao;
	
	/**
	 * 退社情報DAOクラス。<br>
	 */
	RetirementDaoInterface								retirementDao;
	
	/**
	 * 休暇種別管理DAOクラス。<br>
	 */
	HolidayDaoInterface									holidayDao;
	
	/**
	 * 勤怠データDAOクラス。<br>
	 */
	AttendanceDaoInterface								attendanceDao;
	
	/**
	 * カレンダマスタDAOクラス。<br>
	 */
	ScheduleDaoInterface								scheduleDao;
	
	/**
	 * カレンダ日マスタDAOクラス。<br>
	 */
	ScheduleDateDaoInterface							scheduleDateDao;
	
	/**
	 * 残業申請データDAOクラス。<br>
	 */
	OvertimeRequestDaoInterface							overtimeRequestDao;
	
	/**
	 * 休暇申請データDAOクラス。<br>
	 */
	HolidayRequestDaoInterface							holidayRequestDao;
	
	/**
	 * 休日出勤申請データDAOクラス。<br>
	 */
	WorkOnHolidayRequestDaoInterface					workOnHolidayRequestDao;
	
	/**
	 * 代休申請データDAOクラス。<br>
	 */
	SubHolidayRequestDaoInterface						subHolidayRequestDao;
	
	/**
	 * 時差出勤申請データDAOクラス。<br>
	 */
	DifferenceRequestDaoInterface						differenceRequestDao;
	
	/**
	 * ワークフローDAOクラス。<br>
	 */
	WorkflowDaoInterface								workflowDao;
	
	/**
	 * 特別休暇集計データDAOクラス。<br>
	 */
	TotalLeaveDaoInterface								totalLeaveDao;
	
	/**
	 * その他休暇集計データDAOクラス。<br>
	 */
	TotalOtherVacationDaoInterface						totalOtherVacationDao;
	
	/**
	 * 欠勤集計データDAOクラス。<br>
	 */
	TotalAbsenceDaoInterface							totalAbsenceDao;
	
	/**
	 * 手当集計データDAOクラス。<br>
	 */
	TotalAllowanceDaoInterface							totalAllowanceDao;
	
	/**
	 * 手当データDAOクラス。<br>
	 */
	AllowanceDaoInterface								allowanceDao;
	
	/**
	 * 勤怠設定管理DAOクラス。<br>
	 */
	TimeSettingDaoInterface								timeSettingDao;
	
	/**
	 * 振替休日データDAOクラス。<br>
	 */
	SubstituteDaoInterface								substituteDao;
	
	/**
	 * カレンダ管理参照。<br>
	 */
	ScheduleReferenceBeanInterface						schedule;
	
	/**
	 * カレンダ日管理参照。<br>
	 */
	ScheduleDateReferenceBeanInterface					scheduleDate;
	
	/**
	 * 締日ユーティリティインターフェース参照。
	 */
	CutoffUtilBeanInterface								cutoffUtil;
	
	/**
	 * 代休データDAOクラス。<br>
	 */
	SubHolidayDaoInterface								subHolidayDao;
	
	/**
	 * 勤怠情報リスト。<br>
	 */
	
	protected List<AttendanceDtoInterface>				attendanceDtoList;
	
	/**
	 * 休日出勤申請リスト。<br>
	 */
	protected List<WorkOnHolidayRequestDtoInterface>	workOnHolidayRequestDtoList;
	
	/**
	 * 休暇申請リスト。<br>
	 */
	protected List<HolidayRequestDtoInterface>			holidayRequestDtoList;
	
	/**
	 * 代休申請リスト。<br>
	 */
	protected List<SubHolidayRequestDtoInterface>		subHolidayRequestDtoList;
	
	/**
	 * 残業申請リスト。<br>
	 */
	protected List<OvertimeRequestDtoInterface>			overtimeRequestDtoList;
	
	/**
	 * 時差出勤申請リスト。<br>
	 */
	protected List<DifferenceRequestDtoInterface>		differenceRequestDtoList;
	

	/**
	 * {@link PlatformBean#PlatformBean()}を実行する。<br>
	 */
	public TotalTimeCalcBean() {
		super();
	}
	
	/**
	 * {@link PlatformBean#PlatformBean(MospParams, Connection)}を実行する。<br>
	 * @param mospParams MosP処理情報
	 * @param connection DBコネクション
	 */
	public TotalTimeCalcBean(MospParams mospParams, Connection connection) {
		super(mospParams, connection);
	}
	
	@Override
	public void initBean() throws MospException {
		// 継承元のメソッドを実施
		super.initBean();
		// DAO準備
		humanDao = (HumanDaoInterface)createDao(HumanDaoInterface.class);
		entranceDao = (EntranceDaoInterface)createDao(EntranceDaoInterface.class);
		retirementDao = (RetirementDaoInterface)createDao(RetirementDaoInterface.class);
		holidayDao = (HolidayDaoInterface)createDao(HolidayDaoInterface.class);
		attendanceDao = (AttendanceDaoInterface)createDao(AttendanceDaoInterface.class);
		scheduleDao = (ScheduleDaoInterface)createDao(ScheduleDaoInterface.class);
		scheduleDateDao = (ScheduleDateDaoInterface)createDao(ScheduleDateDaoInterface.class);
		overtimeRequestDao = (OvertimeRequestDaoInterface)createDao(OvertimeRequestDaoInterface.class);
		holidayRequestDao = (HolidayRequestDaoInterface)createDao(HolidayRequestDaoInterface.class);
		workOnHolidayRequestDao = (WorkOnHolidayRequestDaoInterface)createDao(WorkOnHolidayRequestDaoInterface.class);
		subHolidayRequestDao = (SubHolidayRequestDaoInterface)createDao(SubHolidayRequestDaoInterface.class);
		differenceRequestDao = (DifferenceRequestDaoInterface)createDao(DifferenceRequestDaoInterface.class);
		workflowDao = (WorkflowDaoInterface)createDao(WorkflowDaoInterface.class);
		totalLeaveDao = (TotalLeaveDaoInterface)createDao(TotalLeaveDaoInterface.class);
		totalOtherVacationDao = (TotalOtherVacationDaoInterface)createDao(TotalOtherVacationDaoInterface.class);
		totalAbsenceDao = (TotalAbsenceDaoInterface)createDao(TotalAbsenceDaoInterface.class);
		totalAllowanceDao = (TotalAllowanceDaoInterface)createDao(TotalAllowanceDaoInterface.class);
		allowanceDao = (AllowanceDaoInterface)createDao(AllowanceDaoInterface.class);
		timeSettingDao = (TimeSettingDaoInterface)createDao(TimeSettingDaoInterface.class);
		substituteDao = (SubstituteDaoInterface)createDao(SubstituteDaoInterface.class);
		schedule = (ScheduleReferenceBeanInterface)createBean(ScheduleReferenceBeanInterface.class);
		scheduleDate = (ScheduleDateReferenceBeanInterface)createBean(ScheduleDateReferenceBeanInterface.class);
		cutoffUtil = (CutoffUtilBeanInterface)createBean(CutoffUtilBeanInterface.class);
		subHolidayDao = (SubHolidayDaoInterface)createDao(SubHolidayDaoInterface.class);
	}
	
	@Override
	public List<CutoffErrorListDtoInterface> calc(TotalTimeDataDtoInterface dto, String personalId,
			int calculationYear, int calculationMonth, String cutoffCode) throws MospException {
		// 集計時エラー情報リスト準備
		List<CutoffErrorListDtoInterface> list = new ArrayList<CutoffErrorListDtoInterface>();
		// 締日コードから締日情報を取得(年月初日時点)
		CutoffDtoInterface cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return list;
		}
		// 未承認仮締設定取得(true：未承認仮締有効)
		boolean noApproval = cutoffDto.getNoApproval() == 0;
		// 締期間の初日を取得
		Date firstDate = getCutoffTermFirstDate(personalId, calculationYear, calculationMonth, cutoffDto);
		// 締期間の初日を確認
		if (firstDate == null) {
			return list;
		}
		// 締期間の最終日を取得
		Date lastDate = getCutoffTermLastDate(personalId, calculationYear, calculationMonth, cutoffDto);
		// 締期間の最終日を確認
		if (lastDate == null) {
			return list;
		}
		// 設定適用情報取得
		Map<Date, ApplicationDtoInterface> map = applicationRefer.findForTerm(personalId, firstDate, lastDate);
		// 各種変数宣言及び初期化
		int workTime = 0;
		int specificWorkTime = 0;
		double timesWorkDate = 0;
		int timesWork = 0;
		double legalWorkOnHoliday = 0;
		double specificWorkOnHoliday = 0;
		int timesAchievement = 0;
		int timesTotalWorkDate = 0;
		int directStart = 0;
		int directEnd = 0;
		int restTime = 0;
		int restLateNight = 0;
		int restWorkOnSpecificHoliday = 0;
		int restWorkOnHoliday = 0;
		int publicTime = 0;
		int privateTime = 0;
		int overtime = 0;
		int overtimeIn = 0;
		int overtimeOut = 0;
		int lateNight = 0;
		int workOnSpecificHoliday = 0;
		int workOnHoliday = 0;
		int decreaseTime = 0;
		int fortyFiveHourOvertime = 0;
		int timesOvertime = 0;
		int timesWorkingHoliday = 0;
		int lateDays = 0;
		int lateThirtyMinutesOrMore = 0;
		int lateLessThanThirtyMinutes = 0;
		int lateTime = 0;
		int lateThirtyMinutesOrMoreTime = 0;
		int lateLessThanThirtyMinutesTime = 0;
		int timesLate = 0;
		int leaveEarlyDays = 0;
		int leaveEarlyThirtyMinutesOrMore = 0;
		int leaveEarlyLessThanThirtyMinutes = 0;
		int leaveEarlyTime = 0;
		int leaveEarlyThirtyMinutesOrMoreTime = 0;
		int leaveEarlyLessThanThirtyMinutesTime = 0;
		int timesLeaveEarly = 0;
		int timesHoliday = 0;
		int timesLegalHoliday = 0;
		int timesSpecificHoliday = 0;
		double timesPaidHoliday = 0;
		int paidHolidayHour = 0;
		double timesStockHoliday = 0;
		double timesCompensation = 0;
		double timesLegalCompensation = 0;
		double timesSpecificCompensation = 0;
		double timesLateCompensation = 0;
		double timesHolidaySubstitute = 0;
		double timesLegalHolidaySubstitute = 0;
		double timesSpecificHolidaySubstitute = 0;
		double totalSpecialHoliday = 0;
		double totalOtherHoliday = 0;
		double totalAbsence = 0;
		int totalAllowance = 0;
		int sixtyHourOvertime = 0;
		int weekDayOvertime = 0;
		int specificOvertime = 0;
		double timesAlternative = 0;
		double legalCompensationUnused = 0;
		double specificCompensationUnused = 0;
		double lateCompensationUnused = 0;
		// 締期間における勤怠及び各種申請のリスト取得
		attendanceDtoList = attendanceDao.findForList(personalId, firstDate, lastDate);
		workOnHolidayRequestDtoList = workOnHolidayRequestDao.findForList(personalId, firstDate, lastDate);
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, firstDate, lastDate);
		subHolidayRequestDtoList = subHolidayRequestDao.findForList(personalId, firstDate, lastDate);
		overtimeRequestDtoList = overtimeRequestDao.findForList(personalId, firstDate, lastDate);
		differenceRequestDtoList = differenceRequestDao.findForList(personalId, firstDate, lastDate);
		
		Map<Date, int[]> weekWorkMap = new HashMap<Date, int[]>();
		List<Date> specificHolidayList = new ArrayList<Date>();
		// 計算対象日準備
		Date date = getDateClone(firstDate);
		// 計算対象日毎に処理
		while (!date.after(lastDate)) {
			// 出勤扱いフラグ
			boolean workFlag = false;
			// 出勤対象フラグ
			boolean workDateFlag = false;
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = map.get(date);
			// 設定適用情報確認
			if (applicationDto == null) {
				// 処理無し(次の日へ)
				date = addDay(date, 1);
				continue;
			}
			// 勤怠設定マスタ取得
			TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
					date);
			// 勤怠マスタの存在チェック
			timeSettingRefer.chkExistTimeSetting(timeSettingDto, date);
			// 処理結果確認
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			// 法定代休未使用日数・所定代休未使用日数
			int minusDays = -timeSettingDto.getSubHolidayLimitDate();
			List<SubHolidayDtoInterface> subHolidayDtoList = subHolidayDao.findForList(personalId, addDay(DateUtility
				.addMonth(date, -timeSettingDto.getSubHolidayLimitMonth()), --minusDays));
			for (SubHolidayDtoInterface subHolidayDto : subHolidayDtoList) {
				int subHolidayType = subHolidayDto.getSubHolidayType();
				if (subHolidayType != 1 && subHolidayType != 2) {
					// 所定代休でなく且つ法定代休でない場合
					continue;
				}
				double days = subHolidayDto.getSubHolidayDays();
				double useDays = 0;
				List<SubHolidayRequestDtoInterface> subHolidayRequestDtoList = subHolidayRequestDao.findForList(
						subHolidayDto.getPersonalId(), subHolidayDto.getWorkDate(), subHolidayDto.getTimesWork(),
						subHolidayType);
				for (SubHolidayRequestDtoInterface subHolidayRequestDto : subHolidayRequestDtoList) {
					WorkflowDtoInterface workflowDto = workflowDao.findForKey(subHolidayRequestDto.getWorkflow());
					if (workflowDto == null) {
						continue;
					}
					if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
						continue;
					}
					int range = subHolidayRequestDto.getHolidayRange();
					if (range == 1) {
						// 全休
						useDays++;
					} else if (range == 2 || range == 3) {
						// 午前休又は午後休
						useDays += 0.5;
					}
				}
				days -= useDays;
				if (subHolidayType == 1) {
					// 所定
					specificCompensationUnused += days;
				} else if (subHolidayType == 2) {
					// 法定
					legalCompensationUnused += days;
				}
			}
			// 深夜代休未使用日数
			List<SubHolidayDtoInterface> nightSubHolidayDtoList = subHolidayDao.findForList(personalId, addDay(date,
					-11));
			for (SubHolidayDtoInterface subHolidayDto : nightSubHolidayDtoList) {
				int subHolidayType = subHolidayDto.getSubHolidayType();
				if (subHolidayType != 3) {
					// 深夜代休でない場合
					continue;
				}
				double days = subHolidayDto.getSubHolidayDays();
				double useDays = 0;
				List<SubHolidayRequestDtoInterface> subHolidayRequestDtoList = subHolidayRequestDao.findForList(
						subHolidayDto.getPersonalId(), subHolidayDto.getWorkDate(), subHolidayDto.getTimesWork(),
						subHolidayType);
				for (SubHolidayRequestDtoInterface subHolidayRequestDto : subHolidayRequestDtoList) {
					WorkflowDtoInterface workflowDto = workflowDao.findForKey(subHolidayRequestDto.getWorkflow());
					if (workflowDto == null) {
						continue;
					}
					if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
						continue;
					}
					int range = subHolidayRequestDto.getHolidayRange();
					if (range == 1) {
						// 全休
						useDays++;
					} else if (range == 2 || range == 3) {
						// 午前休又は午後休
						useDays += 0.5;
					}
				}
				days -= useDays;
				if (subHolidayType == 3) {
					// 深夜
					lateCompensationUnused += days;
				}
			}
			
			HumanDtoInterface humanDto = humanDao.findForInfo(personalId, date);
			if (humanDto == null) {
				return list;
			}
			String workTypeCode = getScheduleWorkTypeCode(personalId, date, false);
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			if (workTypeCode == null || workTypeCode.isEmpty()) {
				date = addDay(date, 1);
				continue;
			}
			boolean isLegalHoliday = TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode);
			boolean isPrescribedHoliday = TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode);
			// 全休
			boolean allFlag = false;
			// 午前休
			boolean amFlag = false;
			// 午後休
			boolean pmFlag = false;
			AttendanceDtoInterface attendanceDto = getAttendanceDtoListDto(date);
			// 週40時間時間外計算
			if (attendanceDto == null) {
				weekWorkMap.put(date, getIntArray(0, 0));
			} else {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
				if (workflowDto == null || !PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					weekWorkMap.put(date, getIntArray(0, 0));
				} else {
					if (TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(attendanceDto.getWorkTypeCode())) {
						// 所定休日出勤の場合
						specificHolidayList.add(date);
					}
					weekWorkMap.put(date,
							getIntArray(attendanceDto.getGeneralWorkTime(), attendanceDto.getOvertimeIn()));
				}
			}
			int endWeek = timeSettingDto.getStartWeek() - 1;
			if (endWeek == 0) {
				endWeek = 7;
			}
			if (DateUtility.getDayOfWeek(date) == endWeek) {
				// 曜日が週の終了曜日と一致した場合はその週の週単位の計算を行う
				int count = -6;
				while (count <= 0) {
					if (weekWorkMap.get(addDay(date, count)) == null) {
						if (addDay(date, count).before(firstDate)) {
							// 先月分の勤怠データを取得する
							AttendanceDtoInterface lastMonthAttendanceDto = attendanceDao.findForKey(personalId,
									addDay(date, count), 1);
							if (lastMonthAttendanceDto == null) {
								weekWorkMap.put(addDay(date, count), getIntArray(0, 0));
							} else {
								WorkflowDtoInterface workflowDto = workflowDao.findForKey(lastMonthAttendanceDto
									.getWorkflow());
								if (workflowDto == null
										|| !PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
									weekWorkMap.put(addDay(date, count), getIntArray(0, 0));
								} else {
									if (TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(lastMonthAttendanceDto
										.getWorkTypeCode())) {
										// 所定休日出勤の場合
										specificHolidayList.add(addDay(date, count));
									}
									weekWorkMap.put(addDay(date, count), getIntArray(lastMonthAttendanceDto
										.getGeneralWorkTime(), lastMonthAttendanceDto.getOvertimeIn()));
								}
							}
						}
					}
					count++;
				}
				int weeklyTotalGeneralWorkTime = 0;
				int weeklyTotalOvertimeIn = 0;
				count = -6;
				while (count <= 0) {
					int[] workTimeArray = weekWorkMap.get(addDay(date, count));
					if (workTimeArray == null) {
						count++;
						continue;
					}
					for (int i = 0; i < workTimeArray.length; i++) {
						if (weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn >= 40 * 60) {
							// 所定労働時間及び法内残業時間の合計が40時間以上の場合
							if (specificHolidayList.contains(addDay(date, count))) {
								// 所定休日時間外時間
								specificOvertime += workTimeArray[i];
							} else {
								// 平日時間外時間
								weekDayOvertime += workTimeArray[i];
							}
						} else if (weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn + workTimeArray[i] > 40 * 60) {
							// 所定労働時間及び法内残業時間の合計に加算したら40時間を超える場合
							int over = weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn + workTimeArray[i] - 40 * 60;
							if (specificHolidayList.contains(addDay(date, count))) {
								// 所定休日時間外時間
								specificOvertime += over;
							} else {
								// 平日時間外時間
								weekDayOvertime += over;
							}
						}
						if (i == 0) {
							// 所定労働時間
							weeklyTotalGeneralWorkTime += workTimeArray[i];
						} else if (i == 1) {
							// 法内残業時間
							weeklyTotalOvertimeIn += workTimeArray[i];
						}
					}
					count++;
				}
				int over40Hours = weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn - 40 * 60;
				if (over40Hours > 0) {
					// 所定労働時間及び法内残業時間の合計が40時間を超える場合
					if (weeklyTotalGeneralWorkTime >= 40 * 60) {
						// 所定労働時間が40時間以上の場合は法内残業時間を引く
						overtimeIn -= weeklyTotalOvertimeIn;
					} else if (weeklyTotalOvertimeIn - (40 * 60 - weeklyTotalGeneralWorkTime) > 0) {
						overtimeIn -= weeklyTotalOvertimeIn - (40 * 60 - weeklyTotalGeneralWorkTime);
					}
					overtimeOut += over40Hours;
				}
			}
			if (!noApproval) {
				// 残業
				List<OvertimeRequestDtoInterface> overtimeRequestList = getOvertimeRequestDtoList(date);
				for (OvertimeRequestDtoInterface overtimeRequestDto : overtimeRequestList) {
					WorkflowDtoInterface overtimeRequestWorkflowDto = workflowDao.findForKey(overtimeRequestDto
						.getWorkflow());
					if (overtimeRequestWorkflowDto == null) {
						continue;
					}
					if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(overtimeRequestWorkflowDto.getWorkflowStatus())) {
						// 取下の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_DRAFT.equals(overtimeRequestWorkflowDto.getWorkflowStatus())) {
						// 下書の場合
						continue;
					}
					if (!PlatformConst.CODE_STATUS_COMPLETE.equals(overtimeRequestWorkflowDto.getWorkflowStatus())) {
						// 承認完了でない場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						// TODO
						cutoffErrorListDto.setType("残業");
						cutoffErrorListDto.setState("未承認");
						list.add(cutoffErrorListDto);
					}
				}
				// 時差出勤
				DifferenceRequestDtoInterface differenceRequestDto = getDifferenceRequestDtoListDto(date);
				if (differenceRequestDto != null) {
					WorkflowDtoInterface workflowDto = workflowDao.findForKey(differenceRequestDto.getWorkflow());
					if (workflowDto != null) {
						if (!PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())
								&& !PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())
								&& !PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
							// 取下でなく且つ下書でなく且つ承認完了でない場合
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType("時差");
							cutoffErrorListDto.setState("未承認");
							list.add(cutoffErrorListDto);
						}
					}
				}
			}
			// 休日出勤
			boolean isWorkOnHoliday = false;
			if (isLegalHoliday || isPrescribedHoliday) {
				// 勤務形態が法定休日又は所定休日の場合
				WorkOnHolidayRequestDtoInterface workOnHolidayRequestDto = getWorkOnHolidayRequestDtoListDto(date);
				if (workOnHolidayRequestDto == null) {
					// 休日出勤でない場合
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					date = addDay(date, 1);
					continue;
				}
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(workOnHolidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下の場合
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
					// 下書の場合
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (workOnHolidayRequestDto.getSubstitute() == 2) {
						// 休日出勤の場合
						isWorkOnHoliday = true;
					}
				} else {
					// 承認完了でない場合
					if (!noApproval) {
						// 未承認仮締が無効の場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						cutoffErrorListDto.setType("振出休出");
						cutoffErrorListDto.setState("未承認");
						list.add(cutoffErrorListDto);
						date = addDay(date, 1);
						continue;
					}
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					date = addDay(date, 1);
					continue;
				}
			} else {
				// 休暇
				List<HolidayRequestDtoInterface> holidayRequestList = getHolidayRequestDtoList(date);
				for (HolidayRequestDtoInterface holidayRequestDto : holidayRequestList) {
					WorkflowDtoInterface holidayRequestWorkflowDto = workflowDao.findForKey(holidayRequestDto
						.getWorkflow());
					if (holidayRequestWorkflowDto == null) {
						continue;
					}
					if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(holidayRequestWorkflowDto.getWorkflowStatus())) {
						// 取下の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_DRAFT.equals(holidayRequestWorkflowDto.getWorkflowStatus())) {
						// 下書の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_COMPLETE.equals(holidayRequestWorkflowDto.getWorkflowStatus())) {
						// 承認完了の場合
						if (holidayRequestDto.getHolidayType1() == 1) {
							if ("1".equals(holidayRequestDto.getHolidayType2())) {
								// 有給休暇の場合
								if (holidayRequestDto.getHolidayRange() == 1) {
									// 全休の場合
									timesPaidHoliday++;
									workFlag = true;
									workDateFlag = true;
									allFlag = true;
								} else if (holidayRequestDto.getHolidayRange() == 2
										|| holidayRequestDto.getHolidayRange() == 3) {
									// 半休の場合
									timesPaidHoliday += 0.5;
									workFlag = true;
									workDateFlag = true;
									if (holidayRequestDto.getHolidayRange() == 2) {
										amFlag = true;
									} else if (holidayRequestDto.getHolidayRange() == 3) {
										pmFlag = true;
									}
								} else if (holidayRequestDto.getHolidayRange() == 4) {
									// 時休の場合
									paidHolidayHour++;
								}
							} else if ("2".equals(holidayRequestDto.getHolidayType2())) {
								// ストック休暇の場合
								workFlag = true;
								workDateFlag = true;
								if (holidayRequestDto.getHolidayRange() == 1) {
									// 全休の場合
									timesStockHoliday++;
									allFlag = true;
								} else if (holidayRequestDto.getHolidayRange() == 2
										|| holidayRequestDto.getHolidayRange() == 3) {
									// 半休の場合
									timesStockHoliday += 0.5;
									if (holidayRequestDto.getHolidayRange() == 2) {
										amFlag = true;
									} else if (holidayRequestDto.getHolidayRange() == 3) {
										pmFlag = true;
									}
								}
							}
						} else if (holidayRequestDto.getHolidayType1() == 2 || holidayRequestDto.getHolidayType1() == 3
								|| holidayRequestDto.getHolidayType1() == 4) {
							// 特別休暇・その他休暇・欠勤の場合
							HolidayDtoInterface holidayDto = holidayDao.findForInfo(
									holidayRequestDto.getHolidayType2(), date, holidayRequestDto.getHolidayType1());
							if (holidayDto.getPaidHolidayCalc() == 1) {
								// 出勤扱いの場合
								workFlag = true;
								workDateFlag = true;
							} else if (holidayDto.getPaidHolidayCalc() == 2) {
								// 欠勤扱いの場合
								workDateFlag = true;
							}
							if (holidayRequestDto.getHolidayRange() == 1) {
								allFlag = true;
							} else if (holidayRequestDto.getHolidayRange() == 2) {
								amFlag = true;
							} else if (holidayRequestDto.getHolidayRange() == 3) {
								pmFlag = true;
							}
						}
					} else {
						// 承認完了でない場合
						if (!noApproval) {
							if (date.equals(holidayRequestDto.getRequestStartDate())) {
								// 未承認仮締が無効の場合
								CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
								cutoffErrorListDto.setType("休暇");
								cutoffErrorListDto.setState("未承認");
								list.add(cutoffErrorListDto);
							}
						}
					}
				}
				// 代休
				List<SubHolidayRequestDtoInterface> subHolidayRequestList = getSubHolidayRequestDtoList(date);
				for (SubHolidayRequestDtoInterface subHolidayRequestDto : subHolidayRequestList) {
					WorkflowDtoInterface subHolidayRequestWorkflowDto = workflowDao.findForKey(subHolidayRequestDto
						.getWorkflow());
					if (subHolidayRequestWorkflowDto == null) {
						continue;
					}
					if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(subHolidayRequestWorkflowDto.getWorkflowStatus())) {
						// 取下の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_DRAFT.equals(subHolidayRequestWorkflowDto.getWorkflowStatus())) {
						// 下書の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_COMPLETE.equals(subHolidayRequestWorkflowDto.getWorkflowStatus())) {
						// 承認完了の場合
						SubHolidayDtoInterface subHolidayDto = subHolidayDao.findForKey(subHolidayRequestDto
							.getPersonalId(), subHolidayRequestDto.getWorkDate(), subHolidayRequestDto.getTimesWork(),
								subHolidayRequestDto.getWorkDateSubHolidayType());
						if (subHolidayDto == null) {
							continue;
						}
						int workDateSubHolidayType = subHolidayRequestDto.getWorkDateSubHolidayType();
						int holidayRange = subHolidayRequestDto.getHolidayRange();
						if (holidayRange == 1) {
							// 全休の場合
							if (workDateSubHolidayType == TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
								// 法定代休の場合
								timesLegalCompensation++;
							} else if (workDateSubHolidayType == TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE) {
								// 所定代休の場合
								timesSpecificCompensation++;
							} else if (workDateSubHolidayType == TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
								// 深夜代休の場合
								timesLateCompensation++;
							} else {
								continue;
							}
							timesCompensation++;
							allFlag = true;
						} else if (holidayRange == TimeConst.CODE_HOLIDAY_RANGE_AM || holidayRange == 3) {
							// 半休の場合
							if (workDateSubHolidayType == TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
								// 法定代休の場合
								timesLegalCompensation += 0.5;
							} else if (workDateSubHolidayType == TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE) {
								// 所定代休の場合
								timesSpecificCompensation += 0.5;
							} else if (workDateSubHolidayType == TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
								// 深夜代休の場合
								timesLateCompensation += 0.5;
							} else {
								continue;
							}
							timesCompensation += 0.5;
							if (holidayRange == 2) {
								amFlag = true;
							} else if (holidayRange == 3) {
								pmFlag = true;
							}
						}
					} else {
						// 承認完了でない場合
						if (!noApproval) {
							// 未承認仮締が無効の場合
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType("代休");
							cutoffErrorListDto.setState("未承認");
							list.add(cutoffErrorListDto);
						}
					}
				}
				// 振替休日
				List<SubstituteDtoInterface> substituteList = substituteDao.findForList(personalId, date);
				for (SubstituteDtoInterface substituteDto : substituteList) {
					// 振替休日の休出申請を取得
					WorkOnHolidayRequestDtoInterface workOnHolidayRequestDto = workOnHolidayRequestDao
						.findForWorkflow(substituteDto.getWorkflow());
					if (workOnHolidayRequestDto == null) {
						continue;
					}
					WorkflowDtoInterface workflowDto = workflowDao.findForKey(workOnHolidayRequestDto.getWorkflow());
					if (workflowDto == null) {
						continue;
					}
					if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
						// 取下の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
						// 下書の場合
						continue;
					}
					if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
						// 承認完了の場合
						int substituteRange = substituteDto.getSubstituteRange();
						String substituteType = substituteDto.getSubstituteType();
						if (substituteRange == 1) {
							// 全休の場合
							timesHolidaySubstitute++;
							allFlag = true;
							if (substituteType.equals("legal_holiday")) {
								// 法定振替休日
								timesLegalHolidaySubstitute++;
							} else if (substituteType.equals("prescribed_holiday")) {
								// 所定振替休日
								timesSpecificHolidaySubstitute++;
								
							}
						} else if (substituteRange == 2 || substituteRange == 3) {
							// 午前休又は午後休の場合
							timesHolidaySubstitute += 0.5;
							if (substituteType.equals("legal_holiday")) {
								// 法定振替休日
								timesLegalHolidaySubstitute += 0.5;
							} else if (substituteType.equals("prescribed_holiday")) {
								// 所定振替休日
								timesSpecificHolidaySubstitute += 0.5;
							}
							if (substituteRange == 2) {
								// 午前休の場合
								amFlag = true;
							} else if (substituteRange == 3) {
								// 午後休の場合
								pmFlag = true;
							}
						}
					} else {
						// 承認完了でない場合
						if (!noApproval) {
							// 未承認仮締が無効の場合
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType("振出休出");
							cutoffErrorListDto.setState("未承認");
							list.add(cutoffErrorListDto);
						}
					}
				}
				if (allFlag || (amFlag && pmFlag)) {
					if (workFlag) {
						// 出勤扱い加算
						timesAchievement++;
					}
					if (workDateFlag) {
						// 出勤対象加算
						timesTotalWorkDate++;
					}
					date = addDay(date, 1);
					continue;
				}
			}
			if (attendanceDto == null) {
				if (!noApproval) {
					// 未承認仮締が無効の場合
					CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
					cutoffErrorListDto.setType("勤怠");
					cutoffErrorListDto.setState("未申請");
					list.add(cutoffErrorListDto);
				}
				date = addDay(date, 1);
				continue;
			} else {
				WorkflowDtoInterface attendanceWorkflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
				if (attendanceWorkflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (!PlatformConst.CODE_STATUS_COMPLETE.equals(attendanceWorkflowDto.getWorkflowStatus())) {
					// 承認完了でない場合
					if (!noApproval) {
						// 未承認仮締が無効の場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						cutoffErrorListDto.setType("勤怠");
						cutoffErrorListDto.setState("未承認");
						list.add(cutoffErrorListDto);
					}
					date = addDay(date, 1);
					continue;
				}
				// 出勤の場合
				workTime += attendanceDto.getWorkTime();
				// 所定勤務時間
//				specificWorkTime
				// 出勤日数
				timesWorkDate++;
				if (amFlag || pmFlag) {
					// 半休がある場合は半日(0.5日)分を引く
					timesWorkDate -= 0.5;
				}
				timesWork++;
				if (isWorkOnHoliday) {
					// 休日出勤
					if (isLegalHoliday) {
						// 法定休日出勤
						legalWorkOnHoliday++;
						restWorkOnHoliday += attendanceDto.getRestTime();
						workOnHoliday += attendanceDto.getLegalWorkTime();
					}
					if (isPrescribedHoliday) {
						// 所定休日出勤
						specificWorkOnHoliday++;
						restWorkOnSpecificHoliday += attendanceDto.getRestTime();
						workOnSpecificHoliday += attendanceDto.getSpecificWorkTime();
					}
					timesWorkingHoliday++;
				} else {
					// 休日出勤でない場合
					workFlag = true;
					workDateFlag = true;
				}
				if (attendanceDto.getDirectStart() == 1) {
					directStart++;
				}
				if (attendanceDto.getDirectEnd() == 1) {
					directEnd++;
				}
				restTime += attendanceDto.getRestTime();
				restLateNight += attendanceDto.getNightRestTime();
				publicTime += attendanceDto.getPublicTime();
				privateTime += attendanceDto.getPrivateTime();
				overtime += attendanceDto.getOvertime();
				overtimeIn += attendanceDto.getOvertimeIn();
				overtimeOut += attendanceDto.getOvertimeOut();
				if (!isLegalHoliday && !isPrescribedHoliday) {
					weekDayOvertime += attendanceDto.getOvertimeOut();
				}
				if (isWorkOnHoliday && isPrescribedHoliday) {
					specificOvertime += attendanceDto.getOvertimeOut();
				}
				lateNight += attendanceDto.getLateNightTime();
				decreaseTime += attendanceDto.getDecreaseTime();
				if (attendanceDto.getOvertime() > 0) {
					timesOvertime++;
				}
				if (!noApproval && attendanceDto.getOvertimeAfter() > 0) {
					// 後残業がある場合
					boolean checkOvertimeRequest = true;
					WorkOnHolidayRequestDtoInterface workOnHolidayRequestDto = getWorkOnHolidayRequestDtoListDto(date);
					if (workOnHolidayRequestDto != null) {
						WorkflowDtoInterface workflowDto = workflowDao
							.findForKey(workOnHolidayRequestDto.getWorkflow());
						if (workflowDto != null
								&& PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())
								&& workOnHolidayRequestDto.getSubstitute() == 2) {
							// 振り替えない場合
							checkOvertimeRequest = false;
						}
					}
					if (checkOvertimeRequest) {
						// 残業申請をチェック
						OvertimeRequestDtoInterface overtimeRequestDto = overtimeRequestDao.findForKeyOnWorkflow(
								personalId, date, 2);
						if (overtimeRequestDto == null) {
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType("残業");
							cutoffErrorListDto.setState("未申請");
							list.add(cutoffErrorListDto);
						}
					}
				}
				if (attendanceDto.getLateTime() > 0) {
					// 遅刻時間が0分を超える場合
					lateDays++;
					lateTime += attendanceDto.getLateTime();
					if (attendanceDto.getLateTime() < 30) {
						// 遅刻時間が30分未満の場合
						lateLessThanThirtyMinutes++;
						lateLessThanThirtyMinutesTime += attendanceDto.getLateTime();
					} else {
						// 遅刻時間が30分以上の場合
						lateThirtyMinutesOrMore++;
						lateThirtyMinutesOrMoreTime += attendanceDto.getLateTime();
					}
					timesLate++;
				}
				if (attendanceDto.getLeaveEarlyTime() > 0) {
					// 早退時間が0分を超える場合
					leaveEarlyDays++;
					leaveEarlyTime += attendanceDto.getLeaveEarlyTime();
					if (attendanceDto.getLeaveEarlyTime() < 30) {
						// 遅刻時間が30分未満の場合
						leaveEarlyLessThanThirtyMinutes++;
						leaveEarlyLessThanThirtyMinutesTime += attendanceDto.getLeaveEarlyTime();
					} else {
						// 遅刻時間が30分以上の場合
						leaveEarlyThirtyMinutesOrMore++;
						leaveEarlyThirtyMinutesOrMoreTime += attendanceDto.getLeaveEarlyTime();
					}
					timesLeaveEarly++;
				}
			}
			if (workFlag) {
				// 出勤扱い加算
				timesAchievement++;
			}
			if (workDateFlag) {
				// 出勤対象加算
				timesTotalWorkDate++;
			}
			date = addDay(date, 1);
		}
		// 残業
		if (overtimeOut > 60 * 60) {
			// 法定外残業時間が60時間以上の場合
			sixtyHourOvertime = overtimeOut - 60 * 60;
			fortyFiveHourOvertime = 15 * 60;
		} else if (overtimeOut >= 45 * 60) {
			// 法定外残業時間が45時間以上60時間未満の場合
			sixtyHourOvertime = 0;
			fortyFiveHourOvertime = overtimeOut - 45 * 60;
		}
		// 特別休暇合計日数
		List<TotalLeaveDtoInterface> totalLeaveList = totalLeaveDao.findForList(personalId, calculationYear,
				calculationMonth);
		for (TotalLeaveDtoInterface totalLeaveDto : totalLeaveList) {
			totalSpecialHoliday += totalLeaveDto.getTimes();
		}
		// その他休暇合計日数
		List<TotalOtherVacationDtoInterface> totalOtherVacationList = totalOtherVacationDao.findForList(personalId,
				calculationYear, calculationMonth);
		for (TotalOtherVacationDtoInterface totalOtherVacationDto : totalOtherVacationList) {
			totalOtherHoliday += totalOtherVacationDto.getTimes();
		}
		// 欠勤合計日数
		List<TotalAbsenceDtoInterface> totalAbsenceList = totalAbsenceDao.findForList(personalId, calculationYear,
				calculationMonth);
		for (TotalAbsenceDtoInterface totalAbsenceDto : totalAbsenceList) {
			totalAbsence += totalAbsenceDto.getTimes();
		}
		// 手当合計
		List<TotalAllowanceDtoInterface> totalAllowanceList = totalAllowanceDao.findForList(personalId,
				calculationYear, calculationMonth);
		for (TotalAllowanceDtoInterface totalAllowanceDto : totalAllowanceList) {
			totalAllowance += totalAllowanceDto.getTimes();
		}
		// 代替休暇日数
		ApplicationDtoInterface applicationDto = applicationRefer.findForPerson(personalId, lastDate);
		if (applicationDto == null) {
			return list;
		}
		TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
				lastDate);
		if (timeSettingDto == null) {
			return list;
		}
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setCalculationDate(lastDate);
		dto.setWorkTime(getRoundMinute(workTime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setSpecificWorkTime(specificWorkTime);
		dto.setTimesWorkDate(timesWorkDate);
		dto.setTimesWork(timesWork);
		dto.setLegalWorkOnHoliday(legalWorkOnHoliday);
		dto.setSpecificWorkOnHoliday(specificWorkOnHoliday);
		dto.setTimesAchievement(timesAchievement);
		dto.setTimesTotalWorkDate(timesTotalWorkDate);
		dto.setDirectStart(directStart);
		dto.setDirectEnd(directEnd);
		dto.setRestTime(getRoundMinute(restTime, timeSettingDto.getRoundMonthlyRest(), timeSettingDto
			.getRoundMonthlyRestUnit()));
		dto.setRestLateNight(getRoundMinute(restLateNight, timeSettingDto.getRoundMonthlyRest(), timeSettingDto
			.getRoundMonthlyRestUnit()));
		dto.setRestWorkOnSpecificHoliday(getRoundMinute(restWorkOnSpecificHoliday,
				timeSettingDto.getRoundMonthlyRest(), timeSettingDto.getRoundMonthlyRestUnit()));
		dto.setRestWorkOnHoliday(getRoundMinute(restWorkOnHoliday, timeSettingDto.getRoundMonthlyRest(), timeSettingDto
			.getRoundMonthlyRestUnit()));
		dto.setPublicTime(getRoundMinute(publicTime, timeSettingDto.getRoundMonthlyPublic(), timeSettingDto
			.getRoundMonthlyPublicTime()));
		dto.setPrivateTime(getRoundMinute(privateTime, timeSettingDto.getRoundMonthlyPrivate(), timeSettingDto
			.getRoundMonthlyPrivateTime()));
//		dto.setOvertime(getRoundMinute(overtime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
//			.getRoundMonthlyWorkUnit()));
		dto.setOvertimeIn(getRoundMinute(overtimeIn, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setOvertimeOut(getRoundMinute(overtimeOut, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setOvertime(dto.getOvertimeIn() + dto.getOvertimeOut());
		dto.setLateNight(getRoundMinute(lateNight, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setWorkOnSpecificHoliday(getRoundMinute(workOnSpecificHoliday, timeSettingDto.getRoundMonthlyWork(),
				timeSettingDto.getRoundMonthlyWorkUnit()));
		dto.setWorkOnHoliday(getRoundMinute(workOnHoliday, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setDecreaseTime(getRoundMinute(decreaseTime, timeSettingDto.getRoundMonthlyDecrease(), timeSettingDto
			.getRoundMonthlyDecreaseTime()));
		dto.setFortyFiveHourOvertime(getRoundMinute(fortyFiveHourOvertime, timeSettingDto.getRoundMonthlyWork(),
				timeSettingDto.getRoundMonthlyWorkUnit()));
		dto.setTimesOvertime(timesOvertime);
		dto.setTimesWorkingHoliday(timesWorkingHoliday);
		dto.setLateDays(lateDays);
		dto.setLateThirtyMinutesOrMore(lateThirtyMinutesOrMore);
		dto.setLateLessThanThirtyMinutes(lateLessThanThirtyMinutes);
		dto.setLateTime(getRoundMinute(lateTime, timeSettingDto.getRoundMonthlyLate(), timeSettingDto
			.getRoundMonthlyLateUnit()));
		dto.setLateThirtyMinutesOrMoreTime(getRoundMinute(lateThirtyMinutesOrMoreTime, timeSettingDto
			.getRoundMonthlyLate(), timeSettingDto.getRoundMonthlyLateUnit()));
		dto.setLateLessThanThirtyMinutesTime(getRoundMinute(lateLessThanThirtyMinutesTime, timeSettingDto
			.getRoundMonthlyLate(), timeSettingDto.getRoundMonthlyLateUnit()));
		dto.setTimesLate(timesLate);
		dto.setLeaveEarlyDays(leaveEarlyDays);
		dto.setLeaveEarlyThirtyMinutesOrMore(leaveEarlyThirtyMinutesOrMore);
		dto.setLeaveEarlyLessThanThirtyMinutes(leaveEarlyLessThanThirtyMinutes);
		dto.setLeaveEarlyTime(getRoundMinute(leaveEarlyTime, timeSettingDto.getRoundMonthlyEarly(), timeSettingDto
			.getRoundMonthlyEarlyUnit()));
		dto.setLeaveEarlyThirtyMinutesOrMoreTime(getRoundMinute(leaveEarlyThirtyMinutesOrMoreTime, timeSettingDto
			.getRoundMonthlyEarly(), timeSettingDto.getRoundMonthlyEarlyUnit()));
		dto.setLeaveEarlyLessThanThirtyMinutesTime(getRoundMinute(leaveEarlyLessThanThirtyMinutesTime, timeSettingDto
			.getRoundMonthlyEarly(), timeSettingDto.getRoundMonthlyEarlyUnit()));
		dto.setTimesLeaveEarly(timesLeaveEarly);
		dto.setTimesHoliday(timesHoliday);
		dto.setTimesLegalHoliday(timesLegalHoliday);
		dto.setTimesSpecificHoliday(timesSpecificHoliday);
		dto.setTimesPaidHoliday(timesPaidHoliday);
		dto.setPaidHolidayHour(paidHolidayHour);
		dto.setTimesStockHoliday(timesStockHoliday);
		dto.setTimesCompensation(timesCompensation);
		dto.setTimesLegalCompensation(timesLegalCompensation);
		dto.setTimesSpecificCompensation(timesSpecificCompensation);
		dto.setTimesLateCompensation(timesLateCompensation);
		dto.setTimesHolidaySubstitute(timesHolidaySubstitute);
		dto.setTimesLegalHolidaySubstitute(timesLegalHolidaySubstitute);
		dto.setTimesSpecificHolidaySubstitute(timesSpecificHolidaySubstitute);
		dto.setTotalSpecialHoliday(totalSpecialHoliday);
		dto.setTotalOtherHoliday(totalOtherHoliday);
		dto.setTotalAbsence(totalAbsence);
		dto.setTotalAllowance(totalAllowance);
		dto.setSixtyHourOvertime(getRoundMinute(sixtyHourOvertime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setWeekDayOvertime(getRoundMinute(weekDayOvertime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setSpecificOvertime(getRoundMinute(specificOvertime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setTimesAlternative(timesAlternative);
		dto.setLegalCompensationUnused(legalCompensationUnused);
		dto.setSpecificCompensationUnused(specificCompensationUnused);
		dto.setLateCompensationUnused(lateCompensationUnused);
		return list;
	}
	
	@Override
	public TotalLeaveDtoInterface calcTotalLeave(String personalId, int calculationYear, int calculationMonth,
			String cutoffCode, String holidayCode) throws MospException {
		// 年月指定時の基準日で締日情報取得
		CutoffDtoInterface cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		// 締期間初日取得
		Date firstDate = getCutoffTermFirstDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (firstDate == null) {
			return null;
		}
		// 締期間最終日取得
		Date lastDate = getCutoffTermLastDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (lastDate == null) {
			return null;
		}
		// 回数準備
		double times = 0;
		// 処理対象日準備
		Date date = getDateClone(firstDate);
		// 個人IDと対象期間から休暇申請情報リストを取得
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, firstDate, lastDate);
		// 締期間内の日毎に処理
		while (!date.after(lastDate)) {
			String workTypeCode = getScheduleWorkTypeCode(personalId, date, true);
			if (TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode)
					|| TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
				// 法定休日又は所定休日の場合
				date = addDay(date, 1);
				continue;
			}
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, TimeConst.CODE_HOLIDAYTYPE_SPECIAL,
					holidayCode);
			// 休暇申請毎に処理
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
						times++;
					} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM
							|| holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						times += 0.5;
					}
				}
			}
			date = addDay(date, 1);
		}
		TotalLeaveDtoInterface dto = new TmdTotalLeaveDto();
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setHolidayCode(holidayCode);
		dto.setTimes(times);
		return dto;
	}
	
	@Override
	public TotalOtherVacationDtoInterface calcTotalOtherVacation(String personalId, int calculationYear,
			int calculationMonth, String cutoffCode, String holidayCode) throws MospException {
		// 年月指定時の基準日で締日情報取得
		CutoffDtoInterface cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		// 締期間初日取得
		Date firstDate = getCutoffTermFirstDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (firstDate == null) {
			return null;
		}
		// 締期間最終日取得
		Date lastDate = getCutoffTermLastDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (lastDate == null) {
			return null;
		}
		// 回数準備
		double times = 0;
		// 処理対象日準備
		Date date = getDateClone(firstDate);
		// 個人IDと対象期間から休暇申請情報リストを取得
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, firstDate, lastDate);
		// 締期間内の日毎に処理
		while (!date.after(lastDate)) {
			String workTypeCode = getScheduleWorkTypeCode(personalId, date, true);
			if (TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode)
					|| TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
				// 法定休日又は所定休日の場合
				date = addDay(date, 1);
				continue;
			}
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, TimeConst.CODE_HOLIDAYTYPE_OTHER,
					holidayCode);
			// 休暇申請毎に処理
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
						times++;
					} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM
							|| holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						times += 0.5;
					}
				}
			}
			date = addDay(date, 1);
		}
		TotalOtherVacationDtoInterface dto = new TmdTotalOtherVacationDto();
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setHolidayCode(holidayCode);
		dto.setTimes(times);
		return dto;
	}
	
	@Override
	public TotalAbsenceDtoInterface calcTotalAbsence(String personalId, int calculationYear, int calculationMonth,
			String cutoffCode, String absenceCode) throws MospException {
		// 年月指定時の基準日で締日情報取得
		CutoffDtoInterface cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		// 締期間初日取得
		Date firstDate = getCutoffTermFirstDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (firstDate == null) {
			return null;
		}
		// 締期間最終日取得
		Date lastDate = getCutoffTermLastDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (lastDate == null) {
			return null;
		}
		// 回数準備
		double times = 0;
		// 処理対象日準備
		Date date = getDateClone(firstDate);
		// 個人IDと対象期間から休暇申請情報リストを取得
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, firstDate, lastDate);
		// 締期間内の日毎に処理
		while (!date.after(lastDate)) {
			String workTypeCode = getScheduleWorkTypeCode(personalId, date, true);
			if (TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode)
					|| TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
				// 法定休日又は所定休日の場合
				date = addDay(date, 1);
				continue;
			}
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, TimeConst.CODE_HOLIDAYTYPE_ABSENCE,
					absenceCode);
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
						times++;
					} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM
							|| holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						times += 0.5;
					}
				}
			}
			date = addDay(date, 1);
		}
		TotalAbsenceDtoInterface dto = new TmdTotalAbsenceDto();
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setAbsenceCode(absenceCode);
		dto.setTimes(times);
		return dto;
	}
	
	@Override
	public TotalAllowanceDtoInterface calcTotalAllowance(String personalId, int calculationYear, int calculationMonth,
			String cutoffCode, String allowanceCode) throws MospException {
		// 年月指定時の基準日で締日情報取得
		CutoffDtoInterface cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		// 締期間初日取得
		Date firstDate = getCutoffTermFirstDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (firstDate == null) {
			return null;
		}
		// 締期間最終日取得
		Date lastDate = getCutoffTermLastDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (lastDate == null) {
			return null;
		}
		// 回数準備
		int times = 0;
		// 締期間で手当情報リストを取得
		List<AllowanceDtoInterface> list = allowanceDao.findForList(personalId, allowanceCode, firstDate, lastDate);
		// 手当情報毎に処理
		for (AllowanceDtoInterface allowanceDto : list) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDao.findForKey(personalId,
					allowanceDto.getWorkDate(), allowanceDto.getWorks()).getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 承認完了の場合
				times++;
			}
		}
		TotalAllowanceDtoInterface dto = new TmdTotalAllowanceDto();
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setAllowanceCode(allowanceCode);
		dto.setTimes(times);
		return dto;
	}
	
	@Override
	public int getApprovalStatus(String personalId, int year, int month) throws MospException {
		// 年月指定時の基準日取得
		Date yearMonthTargetDate = TimeUtility.getYearMonthTargetDate(year, month, mospParams);
		// 対象個人ID及び対象日付で勤怠設定情報群を取得し設定
		setApplicationSettings(personalId, yearMonthTargetDate);
		Date firstDate = getCutoffTermFirstDate(personalId, year, month, cutoffDto);
		if (firstDate == null) {
			// 入社していなければ未承認無し
			return TimeConst.CODE_NOT_APPROVED_NONE;
		}
		Date lastDate = getCutoffTermLastDate(personalId, year, month, cutoffDto);
		// 勤怠
		List<AttendanceDtoInterface> attendanceList = attendanceDao.findForList(personalId, firstDate, lastDate);
		for (AttendanceDtoInterface attendanceDto : attendanceList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		// 残業
		List<OvertimeRequestDtoInterface> overtimeRequestList = overtimeRequestDao.findForList(personalId, firstDate,
				lastDate);
		for (OvertimeRequestDtoInterface requestDto : overtimeRequestList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(requestDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		// 休暇
		List<HolidayRequestDtoInterface> holidayRequestList = holidayRequestDao.findForTerm(personalId, firstDate,
				lastDate);
		for (HolidayRequestDtoInterface requestDto : holidayRequestList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(requestDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		// 休日出勤
		List<WorkOnHolidayRequestDtoInterface> workOnHolidayRequestList = workOnHolidayRequestDao.findForList(
				personalId, firstDate, lastDate);
		for (WorkOnHolidayRequestDtoInterface requestDto : workOnHolidayRequestList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(requestDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		// 代休
		List<SubHolidayRequestDtoInterface> subHolidayRequestList = subHolidayRequestDao.findForList(personalId,
				firstDate, lastDate);
		for (SubHolidayRequestDtoInterface requestDto : subHolidayRequestList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(requestDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		// 時差出勤
		List<DifferenceRequestDtoInterface> differenceRequestList = differenceRequestDao.findForList(personalId,
				firstDate, lastDate);
		for (DifferenceRequestDtoInterface requestDto : differenceRequestList) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(requestDto.getWorkflow());
			if (workflowDto == null) {
				continue;
			}
			if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
				// 取下の場合
				continue;
			}
			if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
				// 下書の場合
				continue;
			}
			if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
				// 未承認有り
				return TimeConst.CODE_NOT_APPROVED_EXIST;
			}
		}
		return TimeConst.CODE_NOT_APPROVED_NONE;
	}
	
	/**
	 * 
	 * @param date
	 * @param humanDto
	 * @return
	 */
	private CutoffErrorListDtoInterface getCutoffErrorListDto(Date date, HumanDtoInterface humanDto) {
		CutoffErrorListDtoInterface cutoffErrorListDto = new CutoffErrorListDto();
		cutoffErrorListDto.setDate(date);
		cutoffErrorListDto.setEmployeeCode(humanDto.getEmployeeCode());
		cutoffErrorListDto.setLastName(humanDto.getLastName());
		cutoffErrorListDto.setFirstName(humanDto.getFirstName());
		cutoffErrorListDto.setWorkPlaceCode(humanDto.getWorkPlaceCode());
		cutoffErrorListDto.setEmploymentCode(humanDto.getEmploymentContractCode());
		cutoffErrorListDto.setSectionCode(humanDto.getSectionCode());
		cutoffErrorListDto.setPositionCode(humanDto.getPositionCode());
		return cutoffErrorListDto;
	}
	
	/**
	 * 締期間の初日を取得する。<br>
	 * 対象個人IDの入社日が締期間初日よりも後の場合は、
	 * 入社日を取得する。<br>
	 * @param personalId 対象個人ID
	 * @param calculationYear 計算対象年
	 * @param calculationMonth 計算対象月
	 * @param dto 締日情報
	 * @return 締期間初日
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	private Date getCutoffTermFirstDate(String personalId, int calculationYear, int calculationMonth,
			CutoffDtoInterface dto) throws MospException {
		// 入社日取得
		EntranceDtoInterface entranceDto = entranceDao.findForInfo(personalId);
		// 入社日確認
		if (entranceDto == null) {
			return null;
		}
		// 締期間初日を取得
		Date cutoffTermStartDate = TimeUtility.getCutoffFirstDate(dto.getCutoffDate(), calculationYear,
				calculationMonth);
		// 締期間初日が入社日よりも前の場合
		if (cutoffTermStartDate.before(entranceDto.getEntranceDate())) {
			// 入社日を取得
			return entranceDto.getEntranceDate();
		}
		return cutoffTermStartDate;
	}
	
	/**
	 * 締期間の最終日を取得する。<br>
	 * 対象個人IDの退社日が締期間最終日よりも前の場合は、
	 * 退社日を取得する。<br>
	 * @param personalId 対象個人ID
	 * @param calculationYear 計算対象年
	 * @param calculationMonth 計算対象月
	 * @param dto 締日情報
	 * @return 締期間の最終日
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	private Date getCutoffTermLastDate(String personalId, int calculationYear, int calculationMonth,
			CutoffDtoInterface dto) throws MospException {
		// 締期間最終日を取得
		Date cutoffTermLastDate = TimeUtility.getCutoffLastDate(dto.getCutoffDate(), calculationYear, calculationMonth);
		// 退社日取得
		RetirementDtoInterface retirementDto = retirementDao.findForInfo(personalId);
		// 退社日確認
		if (retirementDto == null) {
			return cutoffTermLastDate;
		}
		// 締期間最終日が退社日よりも後の場合
		if (cutoffTermLastDate.after(retirementDto.getRetirementDate())) {
			return retirementDto.getRetirementDate();
		}
		return cutoffTermLastDate;
	}
	
	/**
	 * 
	 * @param personalId 個人ID
	 * @param date 
	 * @param useSubstitute
	 * @return
	 * @throws MospException
	 */
	private String getScheduleWorkTypeCode(String personalId, Date date, boolean useSubstitute) throws MospException {
		if (useSubstitute) {
			List<SubstituteDtoInterface> list = substituteDao.findForList(personalId, date);
			// 振替休日毎に処理
			for (SubstituteDtoInterface substituteDto : list) {
				// ワークフロー番号からワークフロー情報を取得
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(substituteDto.getWorkflow());
				if (workflowDto == null) {
					continue;
				}
				// もし承認済ならば
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (substituteDto.getSubstituteRange() == 1) {
						// 全休の場合
						return substituteDto.getSubstituteType();
					}
				}
			}
		}
		// 設定適用マスタ情報取得
		ApplicationDtoInterface applicationDto = applicationRefer.findForPerson(personalId, date);
		// 設定適用マスタ存在確認
		applicationRefer.chkExistApplication(applicationDto, date);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		// カレンダマスタ取得
		ScheduleDtoInterface scheduleDto = scheduleDao.findForInfo(applicationDto.getScheduleCode(), date);
		
		schedule.chkExistSchedule(scheduleDto, date);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		ScheduleDateDtoInterface scheduleDateDto = scheduleDateDao.findForInfo(scheduleDto.getScheduleCode(),
				scheduleDto.getActivateDate(), date);
		
		scheduleDate.chkExistScheduleDate(scheduleDateDto, date);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		return scheduleDateDto.getWorkTypeCode();
	}
	
	/**
	 * 勤怠情報リストから対象日の勤怠情報を取得する。<br>
	 * @param targetDate 対象日
	 * @return 勤怠情報
	 */
	protected AttendanceDtoInterface getAttendanceDtoListDto(Date targetDate) {
		// 勤怠情報リストから対象日の勤怠情報を取得
		for (AttendanceDtoInterface dto : attendanceDtoList) {
			// 勤務日確認
			if (targetDate.equals(dto.getWorkDate())) {
				return dto;
			}
		}
		return null;
	}
	
	/**
	 * 休日出勤申請リストから対象日の休日出勤申請を取得する。<br>
	 * @param targetDate 対象日
	 * @return 休日出勤申請
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected WorkOnHolidayRequestDtoInterface getWorkOnHolidayRequestDtoListDto(Date targetDate) throws MospException {
		for (WorkOnHolidayRequestDtoInterface dto : workOnHolidayRequestDtoList) {
			if (targetDate.equals(dto.getRequestDate())) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(dto.getWorkflow());
				if (workflowDto == null) {
					continue;
				}
				if (!PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下でない場合
					return dto;
				}
			}
		}
		return null;
	}
	
	/**
	 * 休暇申請リストから対象日の休暇申請リストを取得する。<br>
	 * @param targetDate 対象日
	 * @return 休暇申請リスト
	 */
	protected List<HolidayRequestDtoInterface> getHolidayRequestDtoList(Date targetDate) {
		List<HolidayRequestDtoInterface> list = new ArrayList<HolidayRequestDtoInterface>();
		for (HolidayRequestDtoInterface dto : holidayRequestDtoList) {
			if (!dto.getRequestStartDate().after(targetDate) && !dto.getRequestEndDate().before(targetDate)) {
				list.add(dto);
			}
		}
		return list;
	}
	
	/**
	 * 休暇申請リストから対象日の休暇申請リストを取得する。<br>
	 * @param targetDate 対象日
	 * @param holidayType 休暇種別1
	 * @param holidayCode 休暇コード
	 * @return 休暇申請リスト
	 */
	protected List<HolidayRequestDtoInterface> getHolidayRequestDtoList(Date targetDate, int holidayType,
			String holidayCode) {
		List<HolidayRequestDtoInterface> list = new ArrayList<HolidayRequestDtoInterface>();
		for (HolidayRequestDtoInterface dto : holidayRequestDtoList) {
			if (dto.getRequestStartDate().after(targetDate)) {
				continue;
			}
			if (dto.getRequestEndDate().before(targetDate)) {
				continue;
			}
			if (holidayType != dto.getHolidayType1()) {
				continue;
			}
			if (holidayCode.equals(dto.getHolidayType2())) {
				list.add(dto);
			}
		}
		return list;
	}
	
	/**
	 * 代休申請リストから対象日の代休申請リストを取得する。<br>
	 * @param targetDate 対象日
	 * @return 代休申請リスト
	 */
	protected List<SubHolidayRequestDtoInterface> getSubHolidayRequestDtoList(Date targetDate) {
		List<SubHolidayRequestDtoInterface> list = new ArrayList<SubHolidayRequestDtoInterface>();
		for (SubHolidayRequestDtoInterface dto : subHolidayRequestDtoList) {
			if (targetDate.equals(dto.getRequestDate())) {
				list.add(dto);
			}
		}
		return list;
	}
	
	/**
	 * 残業申請リストから対象日の残業申請リストを取得する。<br>
	 * @param targetDate 対象日
	 * @return 残業申請リスト
	 */
	protected List<OvertimeRequestDtoInterface> getOvertimeRequestDtoList(Date targetDate) {
		List<OvertimeRequestDtoInterface> list = new ArrayList<OvertimeRequestDtoInterface>();
		for (OvertimeRequestDtoInterface dto : overtimeRequestDtoList) {
			if (targetDate.equals(dto.getRequestDate())) {
				list.add(dto);
			}
		}
		return list;
	}
	
	/**
	 * 時差出勤申請リストから対象日の時差出勤申請を取得する。<br>
	 * @param targetDate 対象日
	 * @return 時差出勤申請
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected DifferenceRequestDtoInterface getDifferenceRequestDtoListDto(Date targetDate) throws MospException {
		for (DifferenceRequestDtoInterface dto : differenceRequestDtoList) {
			if (targetDate.equals(dto.getRequestDate())) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(dto.getWorkflow());
				if (workflowDto == null) {
					continue;
				}
				if (!PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下でない場合
					return dto;
				}
			}
		}
		return null;
	}
	
	/**
	 * 配列取得
	 * @param is 対象
	 * @return 配列
	 */
	private int[] getIntArray(int... is) {
		return is;
	}
	
}
