/*
 * 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.TimeBean;
import jp.mosp.time.bean.ApplicationReferenceBeanInterface;
import jp.mosp.time.bean.CutoffReferenceBeanInterface;
import jp.mosp.time.bean.ScheduleDateReferenceBeanInterface;
import jp.mosp.time.bean.ScheduleReferenceBeanInterface;
import jp.mosp.time.bean.TimeSettingReferenceBeanInterface;
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.CutoffDaoInterface;
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;

/**
 * 勤怠集計クラス。
 */
public class TotalTimeCalcBean extends TimeBean implements TotalTimeCalcBeanInterface {
	
	/**
	 * 人事マスタDAOクラス。<br>
	 */
	HumanDaoInterface									humanDao;
	
	/**
	 * 入社情報DAOクラス。<br>
	 */
	EntranceDaoInterface								entranceDao;
	
	/**
	 * 退社情報DAOクラス。<br>
	 */
	RetirementDaoInterface								retirementDao;
	
	/**
	 * 休暇種別管理DAOクラス。<br>
	 */
	HolidayDaoInterface									holidayDao;
	
	/**
	 * 締日マスタDAOクラス。<br>
	 */
	CutoffDaoInterface									cutoffDao;
	
	/**
	 * 勤怠データ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>
	 */
	ApplicationReferenceBeanInterface					application;
	
	/**
	 * カレンダ管理参照。<br>
	 */
	ScheduleReferenceBeanInterface						schedule;
	
	/**
	 * カレンダ日管理参照。<br>
	 */
	ScheduleDateReferenceBeanInterface					scheduleDate;
	
	/**
	 * 勤怠設定参照。<br>
	 */
	TimeSettingReferenceBeanInterface					timeSetting;
	
	/**
	 * 締日管理参照。<br>
	 */
	CutoffReferenceBeanInterface						cutoff;
	
	/**
	 * 代休データ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 {
		// DAO準備
		humanDao = (HumanDaoInterface)createDao(HumanDaoInterface.class);
		entranceDao = (EntranceDaoInterface)createDao(EntranceDaoInterface.class);
		retirementDao = (RetirementDaoInterface)createDao(RetirementDaoInterface.class);
		holidayDao = (HolidayDaoInterface)createDao(HolidayDaoInterface.class);
		cutoffDao = (CutoffDaoInterface)createDao(CutoffDaoInterface.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);
		application = (ApplicationReferenceBeanInterface)createBean(ApplicationReferenceBeanInterface.class);
		schedule = (ScheduleReferenceBeanInterface)createBean(ScheduleReferenceBeanInterface.class);
		scheduleDate = (ScheduleDateReferenceBeanInterface)createBean(ScheduleDateReferenceBeanInterface.class);
		timeSetting = (TimeSettingReferenceBeanInterface)createBean(TimeSettingReferenceBeanInterface.class);
		cutoff = (CutoffReferenceBeanInterface)createBean(CutoffReferenceBeanInterface.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 = cutoffDao.findForInfo(cutoffCode, DateUtility.getFirstDateOfMonth(
				calculationYear, calculationMonth));
		cutoff.chkExistCutoff(cutoffDto, DateUtility.getFirstDateOfMonth(calculationYear, calculationMonth));
		if (mospParams.hasErrorMessage()) {
			return list;
		}
		boolean noApproval = cutoffDto.getNoApproval() == 0;
		Date startDate = getStartDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (startDate == null) {
			return list;
		}
		Date endDate = getEndDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (endDate == null) {
			return list;
		}
		Map<Date, ApplicationDtoInterface> map = application.findForTerm(personalId, startDate, endDate);
		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 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 lateDeduction = 0;
		int lateNoDeduction = 0;
		int lateOther = 0;
		int lateTime = 0;
		int lateDeductionTime = 0;
		int lateNoDeductionTime = 0;
		int lateOtherTime = 0;
		int timesLate = 0;
		int leaveEarlyDays = 0;
		int leaveEarlyDeduction = 0;
		int leaveEarlyNoDeduction = 0;
		int leaveEarlyOther = 0;
		int leaveEarlyTime = 0;
		int leaveEarlyDeductionTime = 0;
		int leaveEarlyNoDeductionTime = 0;
		int leaveEarlyOtherTime = 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;
		attendanceDtoList = attendanceDao.findForList(personalId, startDate, endDate);
		workOnHolidayRequestDtoList = workOnHolidayRequestDao.findForList(personalId, startDate, endDate);
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, startDate, endDate);
		subHolidayRequestDtoList = subHolidayRequestDao.findForList(personalId, startDate, endDate);
		overtimeRequestDtoList = overtimeRequestDao.findForList(personalId, startDate, endDate);
		differenceRequestDtoList = differenceRequestDao.findForList(personalId, startDate, endDate);
		Map<Date, int[]> weekWorkMap = new HashMap<Date, int[]>();
		Date date = startDate;
		while (!date.after(endDate)) {
			// 出勤扱いフラグ
			boolean workFlag = false;
			// 出勤対象フラグ
			boolean workDateFlag = false;
			HumanDtoInterface humanDto = humanDao.findForInfo(personalId, date);
			if (humanDto == null) {
				// TODO
				mospParams.addErrorMessage("");
				return list;
			}
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = map.get(date);
			// 設定適用情報確認
			if (applicationDto == null) {
				// 処理無し(次の日へ)
				date = addDay(date, 1);
				continue;
			}
			TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
					date);
			timeSetting.chkExistTimeSetting(timeSettingDto, date);
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			String workTypeCode = getScheduleWorkTypeCode(personalId, date);
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			if (workTypeCode == null || workTypeCode.isEmpty()) {
//				return list;
				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, new int[]{ 0, 0 });
			} else {
				weekWorkMap.put(date, new int[]{ attendanceDto.getGeneralWorkTime(), attendanceDto.getOvertimeIn() });
			}
			int endWeek = timeSettingDto.getStartWeek() - 1;
			if (endWeek == 0) {
				endWeek = 7;
			}
			if (DateUtility.getDayOfWeek(date) == endWeek) {
				// 曜日が週の終了曜日と一致した場合はその週の週単位の計算を行う
				int weekTotalWork = 0;
				int fortyOvertime = 0;
				int fortyOvertimeOut = 0;
				int count = -6;
				while (count <= 0) {
					if (weekWorkMap.get(addDay(date, count)) == null) {
						if (addDay(date, count).before(startDate)) {
							// 先月分の休暇データを取得する
							AttendanceDtoInterface lastMonthAttendanceDto = attendanceDao.findForKey(personalId,
									addDay(date, count), 1);
							if (lastMonthAttendanceDto == null) {
								weekWorkMap.put(addDay(date, count), new int[]{ 0, 0 });
							} else {
								weekWorkMap.put(addDay(date, count),
										new int[]{ lastMonthAttendanceDto.getGeneralWorkTime(),
											lastMonthAttendanceDto.getOvertimeIn() });
							}
						}
					}
					count++;
				}
				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 (weekTotalWork >= 40 * 60) {
							// 40時間以上である場合
							fortyOvertimeOut += workTimeArray[i];
							if (i == 0) {
								// 所定労働時間の場合
								fortyOvertime += workTimeArray[i];
							}
						} else if (weekTotalWork + workTimeArray[i] > 40 * 60) {
							fortyOvertimeOut += weekTotalWork + workTimeArray[i] - 40 * 60;
							if (i == 0) {
								// 所定労働時間の場合
								fortyOvertime += weekTotalWork + workTimeArray[i] - 40 * 60;
							}
						}
						weekTotalWork += workTimeArray[i];
					}
					count++;
				}
				overtimeIn += fortyOvertime;
				overtimeOut += fortyOvertimeOut;
				// Map初期化
				weekWorkMap.clear();
			}
			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);
						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())) {
					// 承認完了の場合
					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 == 2 || 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 reWorkOnHolidayRequestDto = getWorkOnHolidayRequestDtoListDto(substituteDto
						.getSubstituteDate());
					if (reWorkOnHolidayRequestDto == null) {
						continue;
					}
					WorkflowDtoInterface workflowDto = workflowDao.findForKey(reWorkOnHolidayRequestDto.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;
				}
				// 出勤の場合
				workFlag = true;
				workDateFlag = true;
				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++;
				}
				if (attendanceDto.getDirectStart() == 1) {
					directStart++;
				}
				if (attendanceDto.getDirectEnd() == 1) {
					directEnd++;
				}
				restTime += attendanceDto.getRestTime();
				restLateNight += attendanceDto.getNightRestTime();
				publicTime += attendanceDto.getPublicTime();
				privateTime += attendanceDto.getPrivateTime();
				overtimeIn += attendanceDto.getOvertime();
				if (overtimeOut >= 60 * 60) {
					// 法定外残業時間が60時間以上の場合
					sixtyHourOvertime += attendanceDto.getOvertimeOut();
					if (isWorkOnHoliday && isPrescribedHoliday) {
						specificOvertime += attendanceDto.getOvertimeOut();
					} else if (!isLegalHoliday && !isPrescribedHoliday) {
						weekDayOvertime += attendanceDto.getOvertimeOut();
					}
				} else if (overtimeOut >= 45 * 60) {
					// 法定外残業時間が45時間以上60時間未満の場合
					if (overtimeOut + attendanceDto.getOvertimeOut() >= 60 * 60) {
						// 法定外残業時間を加えて60時間以上となる場合
						sixtyHourOvertime = attendanceDto.getOvertimeOut() + fortyFiveHourOvertime - 15 * 60;
						if (isWorkOnHoliday && isPrescribedHoliday) {
							specificOvertime += attendanceDto.getOvertimeOut();
						} else if (!isLegalHoliday && !isPrescribedHoliday) {
							weekDayOvertime += attendanceDto.getOvertimeOut();
						}
						fortyFiveHourOvertime = 15 * 60;
					} else if (overtimeOut + attendanceDto.getOvertimeOut() < 60 * 60) {
						// 法定外残業時間を加えても60時間時間未満の場合
						fortyFiveHourOvertime += attendanceDto.getOvertimeOut();
					}
				} else {
					// 法定外残業時間が45時間未満の場合
					if (overtimeOut + attendanceDto.getOvertimeOut() >= 60 * 60) {
						// 法定外残業時間を加えて60時間以上となる場合
						sixtyHourOvertime = overtimeOut + attendanceDto.getOvertimeOut() - 60 * 60;
						if (isWorkOnHoliday && isPrescribedHoliday) {
							specificOvertime += attendanceDto.getOvertimeOut();
						} else if (!isLegalHoliday && !isPrescribedHoliday) {
							weekDayOvertime += attendanceDto.getOvertimeOut();
						}
						fortyFiveHourOvertime = 15 * 60;
					} else if (45 * 60 <= overtimeOut + attendanceDto.getOvertimeOut()
							&& overtimeOut + attendanceDto.getOvertimeOut() < 60 * 60) {
						// 法定外残業時間を加えて45時間以上60時間未満となる場合
						fortyFiveHourOvertime += overtimeOut + attendanceDto.getOvertimeOut() - 45 * 60;
					}
				}
				overtimeOut += attendanceDto.getOvertimeOut();
				lateNight += attendanceDto.getLateNightTime();
				decreaseTime += attendanceDto.getDecreaseTime();
				if (attendanceDto.getOvertime() > 0) {
					timesOvertime++;
				}
				if (!noApproval && attendanceDto.getOvertimeAfter() > 0) {
					// 後残業がある場合は残業申請をチェック
					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) {
					lateDays++;
					// 遅刻控除有り日数・遅刻控除無し日数・遅刻その他日数
					if (TimeConst.CODE_TARDINESS_WHY_INDIVIDU.equals(attendanceDto.getLateReason())) {
						// 個人都合(控除あり)
						lateDeduction++;
						lateDeductionTime += attendanceDto.getLateTime();
					} else if (TimeConst.CODE_TARDINESS_WHY_BAD_HEALTH.equals(attendanceDto.getLateReason())) {
						// 体調不良(控除あり)
						lateDeduction++;
						lateDeductionTime += attendanceDto.getLateTime();
					} else if (TimeConst.CODE_TARDINESS_WHY_OTHERS.equals(attendanceDto.getLateReason())) {
						// その他(控除あり)
						lateDeduction++;
						lateDeductionTime += attendanceDto.getLateTime();
					} else if (TimeConst.CODE_TARDINESS_WHY_TRAIN.equals(attendanceDto.getLateReason())) {
						// 電車遅延(控除なし)
						lateNoDeduction++;
						lateNoDeductionTime += attendanceDto.getLateTime();
					} else if (TimeConst.CODE_TARDINESS_WHY_COMPANY.equals(attendanceDto.getLateReason())) {
						// 会社指示(控除なし)
						lateNoDeduction++;
						lateNoDeductionTime += attendanceDto.getLateTime();
					} else {
						// 遅刻その他の場合
						lateOther++;
						lateOtherTime += attendanceDto.getLateTime();
					}
					lateTime += attendanceDto.getLateTime();
					timesLate++;
				}
				if (attendanceDto.getLeaveEarlyTime() > 0) {
					leaveEarlyDays++;
					// 早退控除有り日数・早退控除無し日数・早退その他日数
					if (TimeConst.CODE_LEAVEEARLY_WHY_INDIVIDU.equals(attendanceDto.getLeaveEarlyReason())) {
						// 個人都合(控除あり)
						leaveEarlyDeduction++;
						leaveEarlyDeductionTime += attendanceDto.getLeaveEarlyTime();
					} else if (TimeConst.CODE_LEAVEEARLY_WHY_BAD_HEALTH.equals(attendanceDto.getLeaveEarlyReason())) {
						// 体調不良(控除あり)
						leaveEarlyDeduction++;
						leaveEarlyDeductionTime += attendanceDto.getLeaveEarlyTime();
					} else if (TimeConst.CODE_LEAVEEARLY_WHY_OTHERS.equals(attendanceDto.getLeaveEarlyReason())) {
						// その他(控除あり)
						leaveEarlyDeduction++;
						leaveEarlyDeductionTime += attendanceDto.getLeaveEarlyTime();
					} else if (TimeConst.CODE_LEAVEEARLY_WHY_COMPANY.equals(attendanceDto.getLeaveEarlyReason())) {
						// 会社指示(控除なし)
						leaveEarlyNoDeduction++;
						leaveEarlyNoDeductionTime += attendanceDto.getLeaveEarlyTime();
					} else {
						// 早退その他の場合
						leaveEarlyOther++;
						leaveEarlyOtherTime += attendanceDto.getLeaveEarlyTime();
					}
					leaveEarlyTime += attendanceDto.getLeaveEarlyTime();
					timesLeaveEarly++;
				}
			}
			if (workFlag) {
				// 出勤扱い加算
				timesAchievement++;
			}
			if (workDateFlag) {
				// 出勤対象加算
				timesTotalWorkDate++;
			}
			date = addDay(date, 1);
		}
		// 特別休暇合計日数
		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();
		}
		// 代替休暇日数
//		timesAlternative
		ApplicationDtoInterface applicationDto = map.get(startDate);
		if (applicationDto == null) {
			return list;
		}
		TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(), date);
		if (timeSettingDto == null) {
			return list;
		}
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setCalculationDate(endDate);
		dto.setWorkTime(getRoundMinute(workTime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setSpecificWorkTime(specificWorkTime);
		dto.setTimesWorkDate(timesWorkDate);
		dto.setTimesWork(timesWork);
		dto.setLegalWorkOnHoliday(legalWorkOnHoliday);
		dto.setSpecificWorkOnHoliday(specificWorkOnHoliday);
		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.setOvertimeIn(getRoundMinute(overtimeIn, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setOvertimeOut(getRoundMinute(overtimeOut, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		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.setLateDeduction(lateDeduction);
		dto.setLateNoDeduction(lateNoDeduction);
		dto.setLateOther(lateOther);
		dto.setLateTime(getRoundMinute(lateTime, timeSettingDto.getRoundMonthlyLate(), timeSettingDto
			.getRoundMonthlyLateUnit()));
		dto.setLateDeductionTime(getRoundMinute(lateDeductionTime, timeSettingDto.getRoundMonthlyLate(), timeSettingDto
			.getRoundMonthlyLateUnit()));
		dto.setLateNoDeductionTime(getRoundMinute(lateNoDeductionTime, timeSettingDto.getRoundMonthlyLate(),
				timeSettingDto.getRoundMonthlyLateUnit()));
		dto.setLateOtherTime(getRoundMinute(lateOtherTime, timeSettingDto.getRoundMonthlyLate(), timeSettingDto
			.getRoundMonthlyLateUnit()));
		dto.setTimesLate(timesLate);
		dto.setLeaveEarlyDays(leaveEarlyDays);
		dto.setLeaveEarlyDeduction(leaveEarlyDeduction);
		dto.setLeaveEarlyNoDeduction(leaveEarlyNoDeduction);
		dto.setLeaveEarlyOther(leaveEarlyOther);
		dto.setLeaveEarlyTime(getRoundMinute(leaveEarlyTime, timeSettingDto.getRoundMonthlyEarly(), timeSettingDto
			.getRoundMonthlyEarlyUnit()));
		dto.setLeaveEarlyDeductionTime(getRoundMinute(leaveEarlyDeductionTime, timeSettingDto.getRoundMonthlyEarly(),
				timeSettingDto.getRoundMonthlyEarlyUnit()));
		dto.setLeaveEarlyNoDeductionTime(getRoundMinute(leaveEarlyNoDeductionTime, timeSettingDto
			.getRoundMonthlyEarly(), timeSettingDto.getRoundMonthlyEarlyUnit()));
		dto.setLeaveEarlyOtherTime(getRoundMinute(leaveEarlyOtherTime, 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);
		return list;
	}
	
	@Override
	public TotalLeaveDtoInterface calcTotalLeave(String personalId, int calculationYear, int calculationMonth,
			String cutoffCode, String holidayCode) throws MospException {
		CutoffDtoInterface cutoffDto = cutoffDao.findForInfo(cutoffCode, DateUtility.getFirstDateOfMonth(
				calculationYear, calculationMonth));
		cutoff.chkExistCutoff(cutoffDto, DateUtility.getFirstDateOfMonth(calculationYear, calculationMonth));
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		double times = 0;
		Date startDate = getStartDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (startDate == null) {
			return null;
		}
		Date endDate = getEndDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (endDate == null) {
			return null;
		}
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, startDate, endDate);
		Date date = startDate;
		while (!date.after(endDate)) {
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, 2, holidayCode);
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
					// 下書の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == 1) {
						times++;
					}
					if (holidayRequestDto.getHolidayRange() == 2 || holidayRequestDto.getHolidayRange() == 3) {
						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 = cutoffDao.findForInfo(cutoffCode, DateUtility.getFirstDateOfMonth(
				calculationYear, calculationMonth));
		cutoff.chkExistCutoff(cutoffDto, DateUtility.getFirstDateOfMonth(calculationYear, calculationMonth));
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		double times = 0;
		Date startDate = getStartDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (startDate == null) {
			return null;
		}
		Date endDate = getEndDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (endDate == null) {
			return null;
		}
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, startDate, endDate);
		Date date = startDate;
		while (!date.after(endDate)) {
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, 3, holidayCode);
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
					// 下書の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == 1) {
						times++;
					}
					if (holidayRequestDto.getHolidayRange() == 2 || holidayRequestDto.getHolidayRange() == 3) {
						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 = cutoffDao.findForInfo(cutoffCode, DateUtility.getFirstDateOfMonth(
				calculationYear, calculationMonth));
		cutoff.chkExistCutoff(cutoffDto, DateUtility.getFirstDateOfMonth(calculationYear, calculationMonth));
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		double times = 0;
		Date startDate = getStartDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (startDate == null) {
			return null;
		}
		Date endDate = getEndDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (endDate == null) {
			return null;
		}
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, startDate, endDate);
		Date date = startDate;
		while (!date.after(endDate)) {
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, 4, absenceCode);
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
					// 取下の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
					// 下書の場合
					date = addDay(date, 1);
					continue;
				}
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 承認完了の場合
					if (holidayRequestDto.getHolidayRange() == 1) {
						times++;
					}
					if (holidayRequestDto.getHolidayRange() == 2 || holidayRequestDto.getHolidayRange() == 3) {
						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 = cutoffDao.findForInfo(cutoffCode, DateUtility.getFirstDateOfMonth(
				calculationYear, calculationMonth));
		cutoff.chkExistCutoff(cutoffDto, DateUtility.getFirstDateOfMonth(calculationYear, calculationMonth));
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		Date startDate = getStartDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (startDate == null) {
			return null;
		}
		Date endDate = getEndDate(personalId, calculationYear, calculationMonth, cutoffDto);
		if (endDate == null) {
			return null;
		}
		int times = 0;
		List<AllowanceDtoInterface> list = allowanceDao.findForList(personalId, allowanceCode, startDate, endDate);
		for (AllowanceDtoInterface allowanceDto : list) {
			WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDao.findForKey(personalId,
					allowanceDto.getWorkDate(), allowanceDto.getWorks()).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())) {
				// 承認完了の場合
				times++;
			}
		}
		TotalAllowanceDtoInterface dto = new TmdTotalAllowanceDto();
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setAllowanceCode(allowanceCode);
		dto.setTimes(times);
		return dto;
	}
	
	@Override
	public String getApprovalStatus(String personalId, int year, int month) throws MospException {
		Date targetMonth = DateUtility.getFirstDateOfMonth(year, month);
		ApplicationDtoInterface applicationDto = application.findForMonth(personalId, year, month);
		application.chkExistApplication(applicationDto, targetMonth);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
				targetMonth);
		timeSetting.chkExistTimeSetting(timeSettingDto, targetMonth);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		CutoffDtoInterface cutoffDto = cutoffDao.findForInfo(timeSettingDto.getCutoffCode(), targetMonth);
		cutoff.chkExistCutoff(cutoffDto, targetMonth);
		if (mospParams.hasErrorMessage()) {
			return null;
		}
		Date startDate = getStartDate(personalId, year, month, cutoffDto);
		if (startDate == null) {
			return null;
		}
		Date endDate = getEndDate(personalId, year, month, cutoffDto);
		if (endDate == null) {
			return null;
		}
		/*
				Date date = startDate;
				while (!date.after(endDate)) {
					String workTypeCode = getScheduleWorkTypeCode(personalId, date);
					if (mospParams.hasErrorMessage()) {
						return "1";
					}
					if (workTypeCode == null || workTypeCode.isEmpty()) {
						return "1";
					}
					if (TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode)
							|| TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
						// 勤務形態が法定休日又は所定休日の場合
						WorkOnHolidayRequestDtoInterface workOnHolidayRequestDto = workOnHolidayRequestDao
							.findForKeyOnWorkflow(personalId, date);
						if (workOnHolidayRequestDto == null) {
							// 休日出勤でない場合
							date = addDay(date, 1);
							continue;
						}
						WorkflowDtoInterface workflowDto = workflowDao.findForKey(workOnHolidayRequestDto.getWorkflow());
						if (workflowDto == null) {
							date = addDay(date, 1);
							continue;
						}
						if (PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())) {
							// 取下の場合
							date = addDay(date, 1);
							continue;
						}
						if (PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus())) {
							// 下書の場合
							date = addDay(date, 1);
							continue;
						}
						if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
							// 未承認有り
							return "1";
						}
					}
					// 勤怠
					AttendanceDtoInterface attendanceDto = attendanceDao.findForKey(personalId, date, 1);
					if (attendanceDto == null) {
						// 勤怠がない場合
						boolean allFlag = false;
						boolean amFlag = false;
						boolean pmFlag = false;
						// 休暇
						List<HolidayRequestDtoInterface> holidayRequestList = holidayRequestDao.findForList(personalId, date);
						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 "1";
							}
							int range = requestDto.getHolidayRange();
							if (range == 1) {
								// 全休の場合
								allFlag = true;
							} else if (range == 2) {
								// 午前休の場合
								amFlag = true;
							} else if (range == 3) {
								// 午後休の場合
								pmFlag = true;
							}
						}
						if (allFlag || (amFlag && pmFlag)) {
							date = addDay(date, 1);
							continue;
						}
						// 代休
						List<SubHolidayRequestDtoInterface> subHolidayRequestList = subHolidayRequestDao.findForList(
								personalId, date);
						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 "1";
							}
							int range = requestDto.getHolidayRange();
							if (range == 1) {
								// 全休の場合
								allFlag = true;
							} else if (range == 2) {
								// 午前休の場合
								amFlag = true;
							} else if (range == 3) {
								// 午後休の場合
								pmFlag = true;
							}
						}
						if (allFlag || (amFlag && pmFlag)) {
							date = addDay(date, 1);
							continue;
						}
						// 振替休日
						List<SubstituteDtoInterface> substituteList = substituteDao.findForList(personalId, date, 1);
						for (SubstituteDtoInterface substituteDto : substituteList) {
							WorkflowDtoInterface workflowDto = workflowDao.findForKey(substituteDto.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 "1";
							}
							int range = substituteDto.getSubstituteRange();
							if (range == 1) {
								// 全休の場合
								allFlag = true;
							} else if (range == 2) {
								// 午前休の場合
								amFlag = true;
							} else if (range == 3) {
								// 午後休の場合
								pmFlag = true;
							}
						}
						if (allFlag || (amFlag && pmFlag)) {
							date = addDay(date, 1);
							continue;
						}
					} else {
						WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
						if (workflowDto == null) {
							date = addDay(date, 1);
							continue;
						}
						if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
							// 未承認有り
							return "1";
						}
						if (attendanceDto.getOvertimeAfter() > 0) {
							// 勤務後残業がある場合
							OvertimeRequestDtoInterface overtimeRequestDto = overtimeRequestDao.findForKeyOnWorkflow(
									personalId, date, 2);
							if (overtimeRequestDto == null) {
								// 未承認有り
								return "1";
							}
							WorkflowDtoInterface overtimeRequestWorkflowDto = workflowDao.findForKey(overtimeRequestDto
								.getWorkflow());
							if (overtimeRequestWorkflowDto == null) {
								date = addDay(date, 1);
								continue;
							}
							if (!PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
								// 未承認有り
								return "1";
							}
						}
					}
					date = addDay(date, 1);
				}
		*/
		// 勤怠
		List<AttendanceDtoInterface> attendanceList = attendanceDao.findForList(personalId, startDate, endDate);
		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 "1";
			}
		}
		// 残業
		List<OvertimeRequestDtoInterface> overtimeRequestList = overtimeRequestDao.findForList(personalId, startDate,
				endDate);
		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 "1";
			}
		}
		// 休暇
		List<HolidayRequestDtoInterface> holidayRequestList = holidayRequestDao.findForTerm(personalId, startDate,
				endDate);
		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 "1";
			}
		}
		// 休日出勤
		List<WorkOnHolidayRequestDtoInterface> workOnHolidayRequestList = workOnHolidayRequestDao.findForList(
				personalId, startDate, endDate);
		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 "1";
			}
		}
		// 代休
		List<SubHolidayRequestDtoInterface> subHolidayRequestList = subHolidayRequestDao.findForList(personalId,
				startDate, endDate);
		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 "1";
			}
		}
		// 時差出勤
		List<DifferenceRequestDtoInterface> differenceRequestList = differenceRequestDao.findForList(personalId,
				startDate, endDate);
		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 "1";
			}
		}
		return "0";
	}
	
	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;
	}
	
	private Date getStartDate(String personalId, int calculationYear, int calculationMonth, CutoffDtoInterface dto)
			throws MospException {
		EntranceDtoInterface entranceDto = entranceDao.findForInfo(personalId);
		if (entranceDto == null) {
			return null;
		}
		Date firstDateOfLastMonth = DateUtility.addMonth(DateUtility.getFirstDateOfMonth(calculationYear,
				calculationMonth), -1);
		int lastMonthYear = DateUtility.getYear(firstDateOfLastMonth);
		int lastMonthMonth = DateUtility.getMonth(firstDateOfLastMonth);
		int cutoffDate = dto.getCutoffDate();
		Date startDate = addDay(DateUtility.getLastDateOfMonth(lastMonthYear, lastMonthMonth), 1);
		if (cutoffDate >= 16) {
			// 締日が16日以後の場合
			startDate = addDay(DateUtility.getDate(lastMonthYear, lastMonthMonth, cutoffDate), 1);
		} else if (cutoffDate >= 1 && cutoffDate <= 15) {
			// 締日が1日から15日までの場合
			startDate = addDay(DateUtility.getDate(calculationYear, calculationMonth, cutoffDate), 1);
		}
		if (startDate.before(entranceDto.getEntranceDate())) {
			return entranceDto.getEntranceDate();
		}
		return startDate;
	}
	
	private Date getEndDate(String personalId, int calculationYear, int calculationMonth, CutoffDtoInterface dto)
			throws MospException {
		int cutoffDate = dto.getCutoffDate();
		Date endDate = DateUtility.getLastDateOfMonth(calculationYear, calculationMonth);
		if (cutoffDate >= 16) {
			// 締日が16日以後の場合
			endDate = DateUtility.getDate(calculationYear, calculationMonth, cutoffDate);
		} else if (cutoffDate >= 1 && cutoffDate <= 15) {
			// 締日が1日から15日までの場合
			Date firstDateOfNextMonth = DateUtility.addMonth(DateUtility.getFirstDateOfMonth(calculationYear,
					calculationMonth), 1);
			endDate = DateUtility.getDate(DateUtility.getYear(firstDateOfNextMonth), DateUtility
				.getMonth(firstDateOfNextMonth), cutoffDate);
		}
		RetirementDtoInterface retirementDto = retirementDao.findForInfo(personalId);
		if (retirementDto == null) {
			return endDate;
		}
		if (endDate.after(retirementDto.getRetirementDate())) {
			return retirementDto.getRetirementDate();
		}
		return endDate;
	}
	
	private String getScheduleWorkTypeCode(String personalId, Date date) throws MospException {
		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 = application.findForPerson(personalId, date);
		application.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;
	}
	
}
