/*
 * 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.Calendar;
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.base.TimeBean;
import jp.mosp.time.bean.CutoffUtilBeanInterface;
import jp.mosp.time.bean.ScheduleDateReferenceBeanInterface;
import jp.mosp.time.bean.ScheduleReferenceBeanInterface;
import jp.mosp.time.bean.TotalAbsenceRegistBeanInterface;
import jp.mosp.time.bean.TotalLeaveRegistBeanInterface;
import jp.mosp.time.bean.TotalOtherVacationRegistBeanInterface;
import jp.mosp.time.bean.TotalTimeCalcBeanInterface;
import jp.mosp.time.bean.TotalTimeEmployeeTransactionReferenceBeanInterface;
import jp.mosp.time.bean.TotalTimeReferenceBeanInterface;
import jp.mosp.time.bean.TotalTimeRegistBeanInterface;
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.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.TmdTotalAllowanceDto;
import jp.mosp.time.utils.TimeUtility;

/**
 * 勤怠集計クラス。
 */
public class TotalTimeCalcBean extends TimeApplicationBean implements TotalTimeCalcBeanInterface {
	
	/**
	 * 深夜代休を利用する際、勤務日から数えた未使用日数。<br>
	 */
//	public static final int								SUB_HOLIDAY_UNUSED_DAY		= -11;
	
	/**
	 * 週単位の計算を行う際、カウント数。<br>
	 */
	public static final int								WEEK_CALCULATE_COUNT		= -6;
	
	/**
	 * 所定労働時間及び法内残業時間の基準時間。<br>
	 */
	public static final int								PREDETERMINED_OVERTIME_WORK	= 40;
	
	/**
	 * 法定労働時間及び法定残業時間の基準時間。<br>
	 */
	public static final int								LEGAL_OVERTIME_WORK			= 45;
	
	/**
	 * 人事マスタDAOクラス。<br>
	 */
	protected HumanDaoInterface							humanDao;
	
	/**
	 * 入社情報DAOクラス。<br>
	 */
	protected EntranceDaoInterface						entranceDao;
	
	/**
	 * 退社情報DAOクラス。<br>
	 */
	protected RetirementDaoInterface					retirementDao;
	
	/**
	 * 休暇種別管理DAOクラス。<br>
	 */
	protected HolidayDaoInterface						holidayDao;
	
	/**
	 * 勤怠データDAOクラス。<br>
	 */
	protected AttendanceDaoInterface					attendanceDao;
	
	/**
	 * カレンダマスタDAOクラス。<br>
	 */
	protected ScheduleDaoInterface						scheduleDao;
	
	/**
	 * カレンダ日マスタDAOクラス。<br>
	 */
	protected ScheduleDateDaoInterface					scheduleDateDao;
	
	/**
	 * 残業申請データDAOクラス。<br>
	 */
	protected OvertimeRequestDaoInterface				overtimeRequestDao;
	
	/**
	 * 休暇申請データDAOクラス。<br>
	 */
	protected HolidayRequestDaoInterface				holidayRequestDao;
	
	/**
	 * 休日出勤申請データDAOクラス。<br>
	 */
	protected WorkOnHolidayRequestDaoInterface			workOnHolidayRequestDao;
	
	/**
	 * 代休申請データDAOクラス。<br>
	 */
	protected SubHolidayRequestDaoInterface				subHolidayRequestDao;
	
	/**
	 * 時差出勤申請データDAOクラス。<br>
	 */
	protected DifferenceRequestDaoInterface				differenceRequestDao;
	
	/**
	 * ワークフローDAOクラス。<br>
	 */
	protected WorkflowDaoInterface						workflowDao;
	
	/**
	 * 特別休暇集計データDAOクラス。<br>
	 */
	protected TotalLeaveDaoInterface					totalLeaveDao;
	
	/**
	 * その他休暇集計データDAOクラス。<br>
	 */
	protected TotalOtherVacationDaoInterface			totalOtherVacationDao;
	
	/**
	 * 欠勤集計データDAOクラス。<br>
	 */
	protected TotalAbsenceDaoInterface					totalAbsenceDao;
	
	/**
	 * 手当集計データDAOクラス。<br>
	 */
	protected TotalAllowanceDaoInterface				totalAllowanceDao;
	
	/**
	 * 手当データDAOクラス。<br>
	 */
	protected AllowanceDaoInterface						allowanceDao;
	
	/**
	 * 勤怠設定管理DAOクラス。<br>
	 */
	protected TimeSettingDaoInterface					timeSettingDao;
	
	/**
	 * 振替休日データDAOクラス。<br>
	 */
	protected SubstituteDaoInterface					substituteDao;
	
	/**
	 * カレンダ管理参照。<br>
	 */
	protected ScheduleReferenceBeanInterface			schedule;
	
	/**
	 * カレンダ日管理参照。<br>
	 */
	protected ScheduleDateReferenceBeanInterface		scheduleDate;
	
	/**
	 * 締日ユーティリティインターフェース参照。
	 */
	protected CutoffUtilBeanInterface					cutoffUtil;
	
	/**
	 * 代休データDAOクラス。<br>
	 */
	protected SubHolidayDaoInterface					subHolidayDao;
	
	/**
	 * 特別休暇集計データ登録クラス。<br>
	 */
	protected TotalLeaveRegistBeanInterface				totalLeaveRegist;
	
	/**
	 * その他休暇集計データ登録クラス。<br>
	 */
	protected TotalOtherVacationRegistBeanInterface		totalOtherVacationRegist;
	
	/**
	 * 欠勤集計データ登録クラス。<br>
	 */
	protected TotalAbsenceRegistBeanInterface			totalAbsenceRegist;
	
	/**
	 * 勤怠集計データ登録クラス。<br>
	 */
	protected TotalTimeReferenceBeanInterface			totalTimeRefer;
	
	/**
	 * 勤怠集計データ登録クラス。<br>
	 */
	protected TotalTimeRegistBeanInterface				totalTimeRegist;
	
	/**
	 * 社員勤怠集計管理参照クラス。<br>
	 */
	TotalTimeEmployeeTransactionReferenceBeanInterface	totalTimeEmployee;
	
	/**
	 * 計算対象年。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected int										calculationYear;
	
	/**
	 * 計算対象月。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected int										calculationMonth;
	
	/**
	 * 締日情報。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected CutoffDtoInterface						cutoffDto;
	
	/**
	 * 締期間基準日。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected Date										cutoffTargetDate;
	
	/**
	 * 締期間初日。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected Date										cutoffFirstDate;
	
	/**
	 * 締期間最終日。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected Date										cutoffLastDate;
	
	/**
	 * 締期間集計日。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}で設定される。<br>
	 */
	protected Date										cutoffCalculationDate;
	
	/**
	 * 休暇種別マスタリスト(特別休暇)。<br>
	 */
	protected List<HolidayDtoInterface>					specialHolidayList;
	
	/**
	 * 休暇種別マスタリスト(その他休暇)。<br>
	 */
	protected List<HolidayDtoInterface>					otherHolidayList;
	
	/**
	 * 休暇種別マスタリスト(欠勤)。<br>
	 */
	protected List<HolidayDtoInterface>					absenceList;
	
	/**
	 * 締期間初日(個人)。<br>
	 * {@link TotalTimeCalcBean#calc(String)}等で設定される。<br>
	 * 締期間初日及び入社日から求める。<br>
	 */
	protected Date										personalFirstDate;
	
	/**
	 * 締期間最終日(個人)。<br>
	 * {@link TotalTimeCalcBean#calc(String)}等で設定される。<br>
	 * 締期間最終日及び退職日から求める。<br>
	 */
	protected Date										personalLastDate;
	
	/**
	 * 締期間(個人)対象日リスト。<br>
	 * {@link TotalTimeCalcBean#calc(String)}等で設定される。<br>
	 * 締期間初日(個人)及び締期間最終日(個人)から求める。<br>
	 */
	protected List<Date>								targetDateList;
	
	/**
	 * 設定適用情報群。<br>
	 * 締期間(個人)における日毎の設定適用情報を格納する。<br>
	 * {@link TotalTimeCalcBean#setPersonalInfo(String)}で設定される。<br>
	 */
	protected Map<Date, ApplicationDtoInterface>		applicationMap;
	
	/**
	 * カレンダ日情報群。<br>
	 * 締期間(個人)における日毎のカレンダ日情報を格納する。<br>
	 * {@link TotalTimeCalcBean#calc(String)}等で設定される。<br>
	 */
	protected Map<Date, ScheduleDateDtoInterface>		scheduleMap;
	
	/**
	 * 振替休日情報群。<br>
	 * 締期間(個人)における日毎の振替休日情報を格納する。<br>
	 * {@link TotalTimeCalcBean#calc(String)}等で設定される。<br>
	 */
	protected Map<Date, SubstituteDtoInterface>			substituteMap;
	
	/**
	 * 勤怠情報リスト。<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();
		// Bean及び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);
		totalLeaveRegist = (TotalLeaveRegistBeanInterface)createBean(TotalLeaveRegistBeanInterface.class);
		totalOtherVacationRegist = (TotalOtherVacationRegistBeanInterface)createBean(TotalOtherVacationRegistBeanInterface.class);
		totalAbsenceRegist = (TotalAbsenceRegistBeanInterface)createBean(TotalAbsenceRegistBeanInterface.class);
		totalTimeRefer = (TotalTimeReferenceBeanInterface)createBean(TotalTimeReferenceBeanInterface.class);
		totalTimeRegist = (TotalTimeRegistBeanInterface)createBean(TotalTimeRegistBeanInterface.class);
		totalTimeEmployee = (TotalTimeEmployeeTransactionReferenceBeanInterface)createBean(TotalTimeEmployeeTransactionReferenceBeanInterface.class);
	}
	
	@Override
	public void setCalculationInfo(int calculationYear, int calculationMonth, String cutoffCode) throws MospException {
		// 対象年月設定
		this.calculationYear = calculationYear;
		this.calculationMonth = calculationMonth;
		// 締日情報取得
		cutoffDto = cutoffUtil.getCutoff(cutoffCode, calculationYear, calculationMonth);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return;
		}
		// 締日取得
		int cutoffDate = cutoffDto.getCutoffDate();
		// 締期間基準日設定
		cutoffTargetDate = TimeUtility.getCutoffTermTargetDate(cutoffDate, calculationYear, calculationMonth);
		// 締期間初日設定
		cutoffFirstDate = TimeUtility.getCutoffFirstDate(cutoffDate, calculationYear, calculationMonth);
		// 締期間最終日設定
		cutoffLastDate = TimeUtility.getCutoffLastDate(cutoffDate, calculationYear, calculationMonth);
		// 締期間集計日設定
		cutoffCalculationDate = TimeUtility.getCutoffCalculationDate(cutoffDate, calculationYear, calculationMonth);
		// 休暇種別設定
		specialHolidayList = holidayDao.findForActivateDate(cutoffTargetDate, TimeConst.CODE_HOLIDAYTYPE_SPECIAL);
		otherHolidayList = holidayDao.findForActivateDate(cutoffTargetDate, TimeConst.CODE_HOLIDAYTYPE_OTHER);
		absenceList = holidayDao.findForActivateDate(cutoffTargetDate, TimeConst.CODE_HOLIDAYTYPE_ABSENCE);
	}
	
	@Override
	public List<CutoffErrorListDtoInterface> calc(String personalId) throws MospException {
		// 社員勤怠集計管理情報取得
		Integer state = totalTimeEmployee.getCutoffState(personalId, calculationYear, calculationMonth);
		// 社員勤怠集計管理情報確認(未締でない場合)
		if (state != null && state.intValue() != TimeConst.CODE_CUTOFF_STATE_NOT_TIGHT) {
			// 計算不要
			return new ArrayList<CutoffErrorListDtoInterface>();
		}
		// 締期間初日(個人)設定
		personalFirstDate = getPersonalFirstDate(personalId);
		// 締期間最終日(個人)設定
		personalLastDate = getPersonalLastDate(personalId);
		// 締期間(個人)確認
		if (personalFirstDate == null || personalLastDate == null) {
			// 計算対象外
			return new ArrayList<CutoffErrorListDtoInterface>();
		}
		// 個人計算情報設定
		setPersonalInfo(personalId);
		// カレンダ日情報群取得
		scheduleMap = getScheduleMap(personalId);
		// 振替休日情報群取得
		substituteMap = getSubstituteMap(personalId);
		// 処理結果確認(個人計算情報設定等に失敗した場合)
		if (mospParams.hasErrorMessage()) {
			// エラーがあるため集計不能
			return null;
		}
		// 特別休暇集計
		double totalSpecialHoliday = calcToalLeave(personalId, true);
		// その他休暇集計
		double totalOtherHoliday = calcTotalOtherVacation(personalId, true);
		// 欠勤集計
		double totalAbsence = calcTotalAbsence(personalId, true);
		// 勤怠集計データ取得
		TotalTimeDataDtoInterface dto = totalTimeRefer.findForKey(personalId, calculationYear, calculationMonth);
		if (dto == null) {
			dto = totalTimeRegist.getInitDto();
		}
		// 勤怠集計データに値を設定
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setCalculationDate(cutoffCalculationDate);
		dto.setTotalSpecialHoliday(totalSpecialHoliday);
		dto.setTotalOtherHoliday(totalOtherHoliday);
		dto.setTotalAbsence(totalAbsence);
		// 勤怠集計
		return calcTime(personalId, dto, true);
	}
	
	@Override
	public TotalTimeDataDtoInterface getTotaledTimeData(String personalId) throws MospException {
		// 社員勤怠集計管理情報取得
		Integer state = totalTimeEmployee.getCutoffState(personalId, calculationYear, calculationMonth);
		// 社員勤怠集計管理情報確認(未締でない場合)
		if (state != null && state.intValue() != TimeConst.CODE_CUTOFF_STATE_NOT_TIGHT) {
			// 勤怠集計情報取得
			TotalTimeDataDtoInterface totalTimeDataDto = totalTimeRefer.findForKey(personalId, calculationYear,
					calculationMonth);
			// 勤怠集計情報確認
			if (totalTimeDataDto != null) {
				// 計算不要
				return totalTimeDataDto;
			}
		}
		// 締期間初日(個人)設定
		personalFirstDate = getPersonalFirstDate(personalId);
		// 締期間最終日(個人)設定
		personalLastDate = getPersonalLastDate(personalId);
		// 締期間(個人)確認
		if (personalFirstDate == null || personalLastDate == null) {
			// 計算対象外
			return null;
		}
		// 個人計算情報設定
		setPersonalInfo(personalId);
		// カレンダ日情報群取得
		scheduleMap = getScheduleMap(personalId);
		// 振替休日情報群取得
		substituteMap = getSubstituteMap(personalId);
		// 処理結果確認(個人計算情報設定等に失敗した場合)
		if (mospParams.hasErrorMessage()) {
			// エラーがあるため集計不能
			return null;
		}
		// 特別休暇集計
		double totalSpecialHoliday = calcToalLeave(personalId, false);
		// その他休暇集計
		double totalOtherHoliday = calcTotalOtherVacation(personalId, false);
		// 欠勤集計
		double totalAbsence = calcTotalAbsence(personalId, false);
		// 勤怠集計データ取得
		TotalTimeDataDtoInterface dto = totalTimeRegist.getInitDto();
		// 勤怠集計データに値を設定
		dto.setPersonalId(personalId);
		dto.setCalculationYear(calculationYear);
		dto.setCalculationMonth(calculationMonth);
		dto.setCalculationDate(cutoffCalculationDate);
		dto.setTotalSpecialHoliday(totalSpecialHoliday);
		dto.setTotalOtherHoliday(totalOtherHoliday);
		dto.setTotalAbsence(totalAbsence);
		// 勤怠集計
		calcTime(personalId, dto, false);
		return dto;
	}
	
	/**
	 * 個人計算情報を設定する。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}
	 * で設定された計算情報を基に、対象個人IDの個人計算情報を設定する。<br>
	 * @param personalId 対象個人ID
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected void setPersonalInfo(String personalId) throws MospException {
		// 締期間(個人)対象日リスト設定
		targetDateList = TimeUtility.getDateList(personalFirstDate, personalLastDate);
		// 設定適用情報群設定
		applicationMap = applicationRefer.findForTerm(personalId, personalFirstDate, personalLastDate);
		// 締期間(個人)における各種申請リスト設定
		attendanceDtoList = attendanceDao.findForList(personalId, personalFirstDate, personalLastDate);
		holidayRequestDtoList = holidayRequestDao.findForTerm(personalId, personalFirstDate, personalLastDate);
		workOnHolidayRequestDtoList = workOnHolidayRequestDao.findForList(personalId, personalFirstDate,
				personalLastDate);
		subHolidayRequestDtoList = subHolidayRequestDao.findForList(personalId, personalFirstDate, personalLastDate);
		overtimeRequestDtoList = overtimeRequestDao.findForList(personalId, personalFirstDate, personalLastDate);
		differenceRequestDtoList = differenceRequestDao.findForList(personalId, personalFirstDate, personalLastDate);
	}
	
	/**
	 * 勤怠の集計をする。<br>
	 * 集計結果を勤怠集計データに格納する。<br>
	 * @param personalId 対象個人ID
	 * @param dto        勤怠集計データ
	 * @param needRegist 登録要否(true：登録要、false：登録不要)
	 * @return 集計時エラー内容リスト
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected List<CutoffErrorListDtoInterface> calcTime(String personalId, TotalTimeDataDtoInterface dto,
			boolean needRegist) throws MospException {
		// 各種変数宣言及び初期化
		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;
		int totalAllowance = 0;
		int sixtyHourOvertime = 0;
		int weekDayOvertime = 0;
		int specificOvertime = 0;
		double timesAlternative = 0;
		double legalCompensationOccurred = 0;
		double specificCompensationOccurred = 0;
		double lateCompensationOccurred = 0;
		double legalCompensationUnused = 0;
		double specificCompensationUnused = 0;
		double lateCompensationUnused = 0;
		// 集計時エラー情報リスト準備
		List<CutoffErrorListDtoInterface> list = new ArrayList<CutoffErrorListDtoInterface>();
		// 未承認仮締設定取得(true：未承認仮締有効)
		boolean noApproval = cutoffDto.getNoApproval() == 0;
		Map<Date, int[]> weekWorkMap = new HashMap<Date, int[]>();
		List<Date> specificHolidayList = new ArrayList<Date>();
		// 計算対象日毎に処理
		for (Date date : targetDateList) {
			// 出勤扱いフラグ
			boolean workFlag = false;
			// 出勤対象フラグ
			boolean workDateFlag = false;
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = applicationMap.get(date);
			// 設定適用情報確認
			if (applicationDto == null) {
				// 処理無し(次の日へ)
				continue;
			}
			// 勤怠設定マスタ取得
			TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
					date);
			// 勤怠マスタの存在チェック
			timeSettingRefer.chkExistTimeSetting(timeSettingDto, date);
			// 処理結果確認
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			// 法定代休未使用日数・所定代休未使用日数
			List<SubHolidayDtoInterface> subHolidayUnusedList = subHolidayDao.findForList(personalId, addDay(
					DateUtility.addMonth(date, -timeSettingDto.getSubHolidayLimitMonth()), -timeSettingDto
						.getSubHolidayLimitDate()));
			for (SubHolidayDtoInterface subHolidayDto : subHolidayUnusedList) {
				int subHolidayType = subHolidayDto.getSubHolidayType();
				if (subHolidayType != TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE
						&& subHolidayType != TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
					// 所定代休でなく且つ法定代休でない場合
					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 == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
						// 全休
						useDays++;
					} else if (range == TimeConst.CODE_HOLIDAY_RANGE_AM || range == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						// 午前休又は午後休
						useDays += TimeConst.HOLIDAY_TIMES_HALF;
					}
				}
				days -= useDays;
				if (subHolidayType == TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE) {
					// 所定
					specificCompensationUnused += days;
				} else if (subHolidayType == TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
					// 法定
					legalCompensationUnused += days;
				}
			}
			// 深夜代休未使用日数
			List<SubHolidayDtoInterface> nightSubHolidayUnusedList = subHolidayDao.findForList(personalId, addDay(
					DateUtility.addMonth(date, -timeSettingDto.getSubHolidayLimitMonth()), -timeSettingDto
						.getSubHolidayLimitDate()));
			for (SubHolidayDtoInterface subHolidayDto : nightSubHolidayUnusedList) {
				int subHolidayType = subHolidayDto.getSubHolidayType();
				if (subHolidayType != TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
					// 深夜代休でない場合
					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 == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
						// 全休
						useDays++;
					} else if (range == TimeConst.CODE_HOLIDAY_RANGE_AM || range == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						// 午前休又は午後休
						useDays += TimeConst.HOLIDAY_TIMES_HALF;
					}
				}
				days -= useDays;
				if (subHolidayType == TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
					// 深夜
					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()) {
				continue;
			}
			// 全休
			boolean allHoliday = false;
			// 午前休
			boolean amHoliday = false;
			// 午後休
			boolean pmHoliday = false;
			AttendanceDtoInterface attendanceDto = getAttendanceDtoListDto(date);
			Date yesterdayDate = addDay(date, -1);
			AttendanceDtoInterface yesterdayAttendanceDto = getAttendanceDtoListDto(yesterdayDate);
			if (yesterdayDate.before(personalFirstDate)) {
				// 先月の場合
				yesterdayAttendanceDto = attendanceDao.findForKey(personalId, yesterdayDate, 1);
			}
			boolean yesterdayWorkOnLegal = false;
			if (yesterdayAttendanceDto != null) {
				// ワークフロ情報取得
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(yesterdayAttendanceDto.getWorkflow());
				yesterdayWorkOnLegal = workflowDto != null
						&& PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())
						&& TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(yesterdayAttendanceDto.getWorkTypeCode());
			}
			// 週40時間時間外計算
			if (attendanceDto == null) {
				int[] yesterdayArray = getIntArray(0, 0);
				if (yesterdayWorkOnLegal) {
					// 前日が法定休日出勤の場合
					yesterdayArray = getIntArray(0, yesterdayAttendanceDto.getOvertimeIn());
				}
				weekWorkMap.put(date, yesterdayArray);
			} else {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
				if (workflowDto == null || !PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					int[] yesterdayArray = getIntArray(0, 0);
					if (yesterdayWorkOnLegal) {
						// 前日が法定休日出勤の場合
						yesterdayArray = getIntArray(0, yesterdayAttendanceDto.getOvertimeIn());
					}
					weekWorkMap.put(date, yesterdayArray);
				} else {
					if (TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(attendanceDto.getWorkTypeCode())) {
						// 所定休日出勤の場合
						specificHolidayList.add(date);
					}
					int todayOvertimeIn = attendanceDto.getOvertimeIn();
					if (TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(attendanceDto.getWorkTypeCode())) {
						// 法定休日出勤の場合
						todayOvertimeIn = 0;
					}
					int yesterdayOvertimeIn = 0;
					if (yesterdayWorkOnLegal) {
						// 前日が法定休日出勤の場合
						if (attendanceDto.getGeneralWorkTime() - attendanceDto.getLateTime()
								- attendanceDto.getLeaveEarlyTime() + attendanceDto.getOvertimeIn() >= TimeConst.TIME_WORKING_HOUR
								* TimeConst.CODE_DEFINITION_HOUR) {
							// 所定労働時間 - 遅刻時間 - 早退時間 + 法内残業時間 が8時間以上の場合
							yesterdayOvertimeIn = 0;
						} else if (attendanceDto.getGeneralWorkTime() - attendanceDto.getLateTime()
								- attendanceDto.getLeaveEarlyTime() + attendanceDto.getOvertimeIn()
								+ yesterdayAttendanceDto.getOvertimeIn() <= TimeConst.TIME_WORKING_HOUR
								* TimeConst.CODE_DEFINITION_HOUR) {
							// 所定労働時間 - 遅刻時間 - 早退時間 + 法内残業時間 + 前日法内残業時間
							// が8時間以下の場合
							yesterdayOvertimeIn = yesterdayAttendanceDto.getOvertimeIn();
						} else {
							yesterdayOvertimeIn = TimeConst.TIME_WORKING_HOUR * TimeConst.CODE_DEFINITION_HOUR
									- attendanceDto.getGeneralWorkTime() + attendanceDto.getLateTime()
									+ attendanceDto.getLeaveEarlyTime() - attendanceDto.getOvertimeIn();
						}
					}
					weekWorkMap.put(date, getIntArray(attendanceDto.getGeneralWorkTime() - attendanceDto.getLateTime()
							- attendanceDto.getLeaveEarlyTime() - attendanceDto.getPrivateTime(), yesterdayOvertimeIn
							+ todayOvertimeIn));
				}
			}
			if (DateUtility.isDayOfWeek(date, getEndDayOfWeek(timeSettingDto.getStartWeek()))) {
				// 曜日が週の終了曜日と一致した場合はその週の週単位の計算を行う
				int count = WEEK_CALCULATE_COUNT;
				while (count <= 0) {
					if (weekWorkMap.get(addDay(date, count)) == null) {
						if (addDay(date, count).before(personalFirstDate)) {
							Date lastMonthDate = addDay(date, count);
							// 先月分の勤怠データを取得する
							AttendanceDtoInterface lastMonthAttendanceDto = attendanceDao.findForKey(personalId,
									lastMonthDate, TimeBean.TIMES_WORK_DEFAULT);
							AttendanceDtoInterface yesterdayLastMonthAttendanceDto = attendanceDao.findForKey(
									personalId, addDay(lastMonthDate, -1), TimeBean.TIMES_WORK_DEFAULT);
							boolean yesterdayLastMonthWorkOnLegal = false;
							if (yesterdayLastMonthAttendanceDto != null) {
								WorkflowDtoInterface workflowDto = workflowDao
									.findForKey(yesterdayLastMonthAttendanceDto.getWorkflow());
								yesterdayLastMonthWorkOnLegal = workflowDto != null
										&& PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())
										&& TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(yesterdayLastMonthAttendanceDto
											.getWorkTypeCode());
							}
							if (lastMonthAttendanceDto == null) {
								int[] yesterdayArray = getIntArray(0, 0);
								if (yesterdayLastMonthWorkOnLegal) {
									// 前日が法定休日出勤の場合
									yesterdayArray = getIntArray(0, yesterdayLastMonthAttendanceDto.getOvertimeIn());
								}
								weekWorkMap.put(lastMonthDate, yesterdayArray);
							} else {
								WorkflowDtoInterface workflowDto = workflowDao.findForKey(lastMonthAttendanceDto
									.getWorkflow());
								if (workflowDto == null
										|| !PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
									int[] yesterdayArray = getIntArray(0, 0);
									if (yesterdayLastMonthWorkOnLegal) {
										// 前日が法定休日出勤の場合
										yesterdayArray = getIntArray(0, yesterdayLastMonthAttendanceDto.getOvertimeIn());
									}
									weekWorkMap.put(lastMonthDate, yesterdayArray);
								} else {
									if (TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(lastMonthAttendanceDto
										.getWorkTypeCode())) {
										// 所定休日出勤の場合
										specificHolidayList.add(lastMonthDate);
									}
									int todayOvertimeIn = lastMonthAttendanceDto.getOvertimeIn();
									if (TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(lastMonthAttendanceDto
										.getWorkTypeCode())) {
										// 法定休日出勤の場合
										todayOvertimeIn = 0;
									}
									int yesterdayOvertimeIn = 0;
									if (yesterdayLastMonthWorkOnLegal) {
										// 前日が法定休日出勤の場合
										if (lastMonthAttendanceDto.getGeneralWorkTime()
												- lastMonthAttendanceDto.getLateTime()
												- lastMonthAttendanceDto.getLeaveEarlyTime()
												+ lastMonthAttendanceDto.getOvertimeIn() >= TimeConst.TIME_WORKING_HOUR
												* TimeConst.CODE_DEFINITION_HOUR) {
											// 所定労働時間 - 遅刻時間 - 早退時間 + 法内残業時間 が8時間以上の場合
											yesterdayOvertimeIn = 0;
										} else if (lastMonthAttendanceDto.getGeneralWorkTime()
												- lastMonthAttendanceDto.getLateTime()
												- lastMonthAttendanceDto.getLeaveEarlyTime()
												+ lastMonthAttendanceDto.getOvertimeIn()
												+ yesterdayLastMonthAttendanceDto.getOvertimeIn() <= TimeConst.TIME_WORKING_HOUR
												* TimeConst.CODE_DEFINITION_HOUR) {
											// 所定労働時間 - 遅刻時間 - 早退時間 + 法内残業時間 + 前日法内残業時間
											// が8時間以下の場合
											yesterdayOvertimeIn = yesterdayLastMonthAttendanceDto.getOvertimeIn();
										} else {
											yesterdayOvertimeIn = TimeConst.TIME_WORKING_HOUR
													* TimeConst.CODE_DEFINITION_HOUR
													- lastMonthAttendanceDto.getGeneralWorkTime()
													+ lastMonthAttendanceDto.getLateTime()
													+ lastMonthAttendanceDto.getLeaveEarlyTime()
													- lastMonthAttendanceDto.getOvertimeIn();
										}
									}
									weekWorkMap.put(lastMonthDate, getIntArray(lastMonthAttendanceDto
										.getGeneralWorkTime()
											- lastMonthAttendanceDto.getLateTime()
											- lastMonthAttendanceDto.getLeaveEarlyTime()
											- lastMonthAttendanceDto.getPrivateTime(), yesterdayOvertimeIn
											+ todayOvertimeIn));
								}
							}
						}
					}
					count++;
				}
				int weeklyTotalGeneralWorkTime = 0;
				int weeklyTotalOvertimeIn = 0;
				int minusOvertimeIn = 0;
				count = WEEK_CALCULATE_COUNT;
				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 >= PREDETERMINED_OVERTIME_WORK
								* TimeConst.CODE_DEFINITION_HOUR) {
							// 所定労働時間及び法内残業時間の合計が40時間以上の場合
							if (specificHolidayList.contains(addDay(date, count))) {
								// 所定休日時間外時間
								specificOvertime += workTimeArray[i];
							} else {
								// 平日時間外時間
								weekDayOvertime += workTimeArray[i];
							}
							if (i == 1) {
								// 法内残業時間
								minusOvertimeIn += workTimeArray[i];
							}
						} else if (weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn + workTimeArray[i] > PREDETERMINED_OVERTIME_WORK
								* TimeConst.CODE_DEFINITION_HOUR) {
							// 所定労働時間及び法内残業時間の合計に加算したら40時間を超える場合
							int over = weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn + workTimeArray[i]
									- PREDETERMINED_OVERTIME_WORK * TimeConst.CODE_DEFINITION_HOUR;
							if (specificHolidayList.contains(addDay(date, count))) {
								// 所定休日時間外時間
								specificOvertime += over;
							} else {
								// 平日時間外時間
								weekDayOvertime += over;
							}
							if (i == 1) {
								// 法内残業時間
								minusOvertimeIn += over;
							}
						}
						if (i == 0) {
							// 所定労働時間
							weeklyTotalGeneralWorkTime += workTimeArray[i];
						} else if (i == 1) {
							// 法内残業時間
							weeklyTotalOvertimeIn += workTimeArray[i];
						}
					}
					count++;
				}
				int over40Hours = weeklyTotalGeneralWorkTime + weeklyTotalOvertimeIn - PREDETERMINED_OVERTIME_WORK
						* TimeConst.CODE_DEFINITION_HOUR;
				if (over40Hours > 0) {
					// 40時間を超える時間を法外残業時間に加算
					overtimeOut += over40Hours;
				}
				overtimeIn -= minusOvertimeIn;
			}
			// 前日の勤怠データ
			boolean overtimeCountFlag = false;
			if (yesterdayWorkOnLegal) {
				// 前日が法定休日出勤の場合は前日の残業時間を加算
				overtime += yesterdayAttendanceDto.getOvertime();
				overtimeOut += yesterdayAttendanceDto.getOvertimeOut();
				// 所定労働時間
				int todayGeneralWorkTime = 0;
				// 法内残業時間
				int todayOvertimeIn = 0;
				if (attendanceDto != null) {
					todayGeneralWorkTime = attendanceDto.getGeneralWorkTime();
					todayOvertimeIn = attendanceDto.getOvertimeIn();
				}
				if (todayGeneralWorkTime + todayOvertimeIn >= TimeConst.TIME_WORKING_HOUR
						* TimeConst.CODE_DEFINITION_HOUR) {
					// 所定労働時間と法内残業時間の合計が8時間以上の場合は
					// 法外残業時間に前日法内残業時間を加算
					overtimeOut += yesterdayAttendanceDto.getOvertimeIn();
				} else if (todayGeneralWorkTime + todayOvertimeIn + yesterdayAttendanceDto.getOvertimeIn() <= TimeConst.TIME_WORKING_HOUR
						* TimeConst.CODE_DEFINITION_HOUR) {
					// 所定労働時間と法内残業時間と前日法内残業時間の合計が8時間以下の場合は
					// 法内残業時間に前日法内残業時間を加算
					overtimeIn += yesterdayAttendanceDto.getOvertimeIn();
				} else {
					int over = TimeConst.TIME_WORKING_HOUR * TimeConst.CODE_DEFINITION_HOUR - todayGeneralWorkTime
							- todayOvertimeIn;
					overtimeIn += over;
					overtimeOut += yesterdayAttendanceDto.getOvertimeIn() - over;
				}
				if (yesterdayAttendanceDto.getOvertime() > 0) {
					// 前日の残業時間がある場合は残業回数を加算
					timesOvertime++;
					overtimeCountFlag = true;
				}
			}
			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(mospParams.getName("OvertimeWork"));
						cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
						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(mospParams.getName("TimeDifference"));
							cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
							list.add(cutoffErrorListDto);
						}
					}
				}
			}
			// 休日出勤
			boolean isWorkOnHoliday = false;
			// 振替出勤
			boolean isWorkOnHolidaySubstitute = false;
			WorkOnHolidayRequestDtoInterface workOnHolidayRequestDto = getWorkOnHolidayRequestDtoListDto(date);
			if (workOnHolidayRequestDto != null) {
				// ワークフロー情報を取得
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(workOnHolidayRequestDto.getWorkflow());
				if (workflowDto != null) {
					if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
						// 承認完了の場合
						int substitute = workOnHolidayRequestDto.getSubstitute();
						if (substitute == TimeConst.CODE_WORK_ON_HOLIDAY_SUBSTITUTE_ON) {
							// 振替出勤の場合
							isWorkOnHolidaySubstitute = true;
						} else if (substitute == TimeConst.CODE_WORK_ON_HOLIDAY_SUBSTITUTE_OFF) {
							// 休日出勤の場合
							isWorkOnHoliday = true;
						}
					} else if (!PlatformConst.CODE_STATUS_WITHDRAWN.equals(workflowDto.getWorkflowStatus())
							&& !PlatformConst.CODE_STATUS_DRAFT.equals(workflowDto.getWorkflowStatus()) && !noApproval) {
						// 取下でなく下書でなく未承認仮締が無効の場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						cutoffErrorListDto.setType("振出休出");
						cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
						list.add(cutoffErrorListDto);
						continue;
					}
				}
			}
			if (!isWorkOnHoliday && !isWorkOnHolidaySubstitute) {
				// 振出・休出でない場合
				// 振替休日
				List<SubstituteDtoInterface> substituteList = substituteDao.findForList(personalId, date);
				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())) {
						// 承認完了の場合
						int substituteRange = substituteDto.getSubstituteRange();
						String substituteType = substituteDto.getSubstituteType();
						if (substituteRange == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
							// 全休の場合
							timesHolidaySubstitute++;
							allHoliday = true;
							if (substituteType.equals(TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY)) {
								// 法定振替休日
								timesLegalHolidaySubstitute++;
							} else if (substituteType.equals(TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY)) {
								// 所定振替休日
								timesSpecificHolidaySubstitute++;
								
							}
						} else if (substituteRange == TimeConst.CODE_HOLIDAY_RANGE_AM
								|| substituteRange == TimeConst.CODE_HOLIDAY_RANGE_PM) {
							// 午前休又は午後休の場合
							timesHolidaySubstitute += TimeConst.HOLIDAY_TIMES_HALF;
							if (substituteType.equals(TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY)) {
								// 法定振替休日
								timesLegalHolidaySubstitute += TimeConst.HOLIDAY_TIMES_HALF;
							} else if (substituteType.equals(TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY)) {
								// 所定振替休日
								timesSpecificHolidaySubstitute += TimeConst.HOLIDAY_TIMES_HALF;
							}
							if (substituteRange == TimeConst.CODE_HOLIDAY_RANGE_AM) {
								// 午前休の場合
								amHoliday = true;
							} else if (substituteRange == TimeConst.CODE_HOLIDAY_RANGE_PM) {
								// 午後休の場合
								pmHoliday = true;
							}
						}
					} else {
						// 承認完了でない場合
						if (!noApproval) {
							// 未承認仮締が無効の場合
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType("振出休出");
							cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
							list.add(cutoffErrorListDto);
						}
					}
				}
			}
			// 休暇
			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 (String.valueOf(TimeConst.CODE_HOLIDAYTYPE_HOLIDAY).equals(
								holidayRequestDto.getHolidayType2())) {
							// 有給休暇の場合
							if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
								// 全休の場合
								timesPaidHoliday++;
								workFlag = true;
								workDateFlag = true;
								allHoliday = true;
							} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM
									|| holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
								// 半休の場合
								timesPaidHoliday += TimeConst.HOLIDAY_TIMES_HALF;
								workFlag = true;
								workDateFlag = true;
								if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM) {
									amHoliday = true;
								} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
									pmHoliday = true;
								}
							} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_TIME) {
								// 時休の場合
								paidHolidayHour++;
							}
						} else if (String.valueOf(TimeConst.CODE_HOLIDAYTYPE_STOCK).equals(
								holidayRequestDto.getHolidayType2())) {
							// ストック休暇の場合
							workFlag = true;
							workDateFlag = true;
							if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_ALL) {
								// 全休の場合
								timesStockHoliday++;
								allHoliday = true;
							} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM
									|| holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
								// 半休の場合
								timesStockHoliday += TimeConst.HOLIDAY_TIMES_HALF;
								if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_AM) {
									amHoliday = true;
								} else if (holidayRequestDto.getHolidayRange() == TimeConst.CODE_HOLIDAY_RANGE_PM) {
									pmHoliday = true;
								}
							}
						}
					} else if (holidayRequestDto.getHolidayType1() == TimeConst.CODE_HOLIDAYTYPE_SPECIAL
							|| holidayRequestDto.getHolidayType1() == TimeConst.CODE_HOLIDAYTYPE_OTHER
							|| holidayRequestDto.getHolidayType1() == TimeConst.CODE_HOLIDAYTYPE_ABSENCE) {
						// 特別休暇・その他休暇・欠勤の場合
						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) {
							allHoliday = true;
						} else if (holidayRequestDto.getHolidayRange() == 2) {
							amHoliday = true;
						} else if (holidayRequestDto.getHolidayRange() == 3) {
							pmHoliday = true;
						}
					}
				} else {
					// 承認完了でない場合
					if (!noApproval) {
						if (date.equals(holidayRequestDto.getRequestStartDate())) {
							// 未承認仮締が無効の場合
							CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
							cutoffErrorListDto.setType(mospParams.getName("Vacation"));
							cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
							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++;
						allHoliday = true;
					} else if (holidayRange == TimeConst.CODE_HOLIDAY_RANGE_AM
							|| holidayRange == TimeConst.CODE_HOLIDAY_RANGE_PM) {
						// 半休の場合
						if (workDateSubHolidayType == TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
							// 法定代休の場合
							timesLegalCompensation += TimeConst.HOLIDAY_TIMES_HALF;
						} else if (workDateSubHolidayType == TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE) {
							// 所定代休の場合
							timesSpecificCompensation += TimeConst.HOLIDAY_TIMES_HALF;
						} else if (workDateSubHolidayType == TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
							// 深夜代休の場合
							timesLateCompensation += TimeConst.HOLIDAY_TIMES_HALF;
						} else {
							continue;
						}
						timesCompensation += TimeConst.HOLIDAY_TIMES_HALF;
						if (holidayRange == TimeConst.CODE_HOLIDAY_RANGE_AM) {
							amHoliday = true;
						} else if (holidayRange == TimeConst.CODE_HOLIDAY_RANGE_PM) {
							pmHoliday = true;
						}
					}
				} else {
					// 承認完了でない場合
					if (!noApproval) {
						// 未承認仮締が無効の場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						cutoffErrorListDto.setType("代休");
						cutoffErrorListDto.setState(mospParams.getName("Ram") + mospParams.getName("Approval"));
						list.add(cutoffErrorListDto);
					}
				}
			}
			if (allHoliday || (amHoliday && pmHoliday)) {
				if (workFlag) {
					// 出勤扱い加算
					timesAchievement++;
				}
				if (workDateFlag) {
					// 出勤対象加算
					timesTotalWorkDate++;
				}
				continue;
			}
			boolean isLegalHoliday = TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode);
			boolean isPrescribedHoliday = TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode);
			if (isLegalHoliday || isPrescribedHoliday) {
				// 勤務形態が法定休日又は所定休日の場合
				if (!isWorkOnHoliday && !isWorkOnHolidaySubstitute) {
					// 休日出勤でなく且つ振替出勤でない場合
					if (isLegalHoliday) {
						// 法定休日
						timesLegalHoliday++;
						timesHoliday++;
					}
					if (isPrescribedHoliday) {
						// 所定休日
						timesSpecificHoliday++;
						timesHoliday++;
					}
					continue;
				}
			}
			if (attendanceDto == null) {
				if (!noApproval) {
					// 未承認仮締が無効の場合
					CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
					cutoffErrorListDto.setType("勤怠");
					cutoffErrorListDto.setState("未申請");
					list.add(cutoffErrorListDto);
				}
				continue;
			} else {
				boolean workOnLegal = isWorkOnHoliday
						&& TimeConst.CODE_WORK_ON_LEGAL_HOLIDAY.equals(attendanceDto.getWorkTypeCode());
				boolean workOnPrescribed = isWorkOnHoliday
						&& TimeConst.CODE_WORK_ON_PRESCRIBED_HOLIDAY.equals(attendanceDto.getWorkTypeCode());
				WorkflowDtoInterface attendanceWorkflowDto = workflowDao.findForKey(attendanceDto.getWorkflow());
				if (attendanceWorkflowDto == null) {
					continue;
				}
				if (!PlatformConst.CODE_STATUS_COMPLETE.equals(attendanceWorkflowDto.getWorkflowStatus())) {
					// 承認完了でない場合
					if (!noApproval) {
						// 未承認仮締が無効の場合
						CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(date, humanDto);
						cutoffErrorListDto.setType("勤怠");
						cutoffErrorListDto.setState("未承認");
						list.add(cutoffErrorListDto);
					}
					continue;
				}
				// 出勤の場合
				workTime += attendanceDto.getWorkTime();
				// 所定勤務時間
//				specificWorkTime
				// 出勤日数
				timesWorkDate++;
				if (amHoliday || pmHoliday) {
					// 半休がある場合は半日(0.5日)分を引く
					timesWorkDate -= TimeConst.HOLIDAY_TIMES_HALF;
				}
				timesWork++;
				workOnHoliday += attendanceDto.getLegalWorkTime();
				if (isWorkOnHoliday) {
					// 休日出勤
					if (workOnLegal) {
						// 法定休日出勤
						legalWorkOnHoliday++;
						restWorkOnHoliday += attendanceDto.getRestTime();
					}
					if (workOnPrescribed) {
						// 所定休日出勤
						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();
				if (!workOnLegal) {
					// 法定休日出勤でない場合は当日の残業時間を加算
					overtime += attendanceDto.getOvertime();
					overtimeIn += attendanceDto.getOvertimeIn();
					overtimeOut += attendanceDto.getOvertimeOut();
				}
				if (!overtimeCountFlag && attendanceDto.getOvertime() > 0) {
					// 残業回数を加算
					timesOvertime++;
				}
				if (!workOnLegal && !workOnPrescribed) {
					// 平日出勤の場合
					weekDayOvertime += attendanceDto.getOvertimeOut();
				}
				if (workOnPrescribed) {
					// 所定休日出勤の場合
					specificOvertime += attendanceDto.getOvertimeOut();
				}
				lateNight += attendanceDto.getLateNightTime();
				decreaseTime += attendanceDto.getDecreaseTime();
				if (!noApproval && !isWorkOnHoliday) {
					// 未承認仮締が無効で且つ休日出勤でない場合
					// 残業申請チェック
					checkOvertimeRequest(list, attendanceDto, humanDto, amHoliday, pmHoliday);
				}
				if (attendanceDto.getLateTime() > 0) {
					// 遅刻時間が0分を超える場合
					lateDays++;
					lateTime += attendanceDto.getLateTime();
					if (attendanceDto.getLateTime() < TimeConst.TIME_HURF_HOUR_MINUTES) {
						// 遅刻時間が30分未満の場合
						lateLessThanThirtyMinutes++;
						lateLessThanThirtyMinutesTime += attendanceDto.getLateTime();
					} else {
						// 遅刻時間が30分以上の場合
						lateThirtyMinutesOrMore++;
						lateThirtyMinutesOrMoreTime += attendanceDto.getLateTime();
					}
					timesLate++;
				}
				if (attendanceDto.getLeaveEarlyTime() > 0) {
					// 早退時間が0分を超える場合
					leaveEarlyDays++;
					leaveEarlyTime += attendanceDto.getLeaveEarlyTime();
					if (attendanceDto.getLeaveEarlyTime() < TimeConst.TIME_HURF_HOUR_MINUTES) {
						// 遅刻時間が30分未満の場合
						leaveEarlyLessThanThirtyMinutes++;
						leaveEarlyLessThanThirtyMinutesTime += attendanceDto.getLeaveEarlyTime();
					} else {
						// 遅刻時間が30分以上の場合
						leaveEarlyThirtyMinutesOrMore++;
						leaveEarlyThirtyMinutesOrMoreTime += attendanceDto.getLeaveEarlyTime();
					}
					timesLeaveEarly++;
				}
				// 法定代休発生日数・所定代休発生日数・深夜代休発生日数
				List<SubHolidayDtoInterface> subHolidayOccurredList = subHolidayDao.findForList(personalId, date);
				for (SubHolidayDtoInterface subHolidayDto : subHolidayOccurredList) {
					int subHolidayType = subHolidayDto.getSubHolidayType();
					double subHolidayDays = subHolidayDto.getSubHolidayDays();
					if (subHolidayType == TimeConst.CODE_LEGAL_SUBHOLIDAY_CODE) {
						// 法定代休の場合
						legalCompensationOccurred += subHolidayDays;
						continue;
					} else if (subHolidayType == TimeConst.CODE_PRESCRIBED_SUBHOLIDAY_CODE) {
						// 所定代休の場合
						specificCompensationOccurred += subHolidayDays;
						continue;
					} else if (subHolidayType == TimeConst.CODE_MIDNIGHT_SUBHOLIDAY_CODE) {
						// 深夜代休の場合
						lateCompensationOccurred += subHolidayDays;
					}
				}
				// 所定勤務時間
				specificWorkTime += getSpecificWorkTime(attendanceDto);
			}
			if (workFlag) {
				// 出勤扱い加算
				timesAchievement++;
			}
			if (workDateFlag) {
				// 出勤対象加算
				timesTotalWorkDate++;
			}
		}
		// 残業
		if (overtimeOut > TimeConst.CODE_DEFINITION_HOUR * TimeConst.CODE_DEFINITION_HOUR) {
			// 法定外残業時間が60時間以上の場合
			sixtyHourOvertime = overtimeOut - TimeConst.CODE_DEFINITION_HOUR * TimeConst.CODE_DEFINITION_HOUR;
			fortyFiveHourOvertime = 15 * TimeConst.CODE_DEFINITION_HOUR;
		} else if (overtimeOut >= LEGAL_OVERTIME_WORK * TimeConst.CODE_DEFINITION_HOUR) {
			// 法定外残業時間が45時間以上60時間未満の場合
			sixtyHourOvertime = 0;
			fortyFiveHourOvertime = overtimeOut - LEGAL_OVERTIME_WORK * TimeConst.CODE_DEFINITION_HOUR;
		}
		// 手当合計
		List<TotalAllowanceDtoInterface> totalAllowanceList = totalAllowanceDao.findForList(personalId,
				calculationYear, calculationMonth);
		for (TotalAllowanceDtoInterface totalAllowanceDto : totalAllowanceList) {
			totalAllowance += totalAllowanceDto.getTimes();
		}
		// 勤怠設定情報取得
		ApplicationDtoInterface applicationDto = applicationMap.get(personalLastDate);
		if (applicationDto == null) {
			return list;
		}
		TimeSettingDtoInterface timeSettingDto = timeSettingDao.findForInfo(applicationDto.getWorkSettingCode(),
				personalLastDate);
		if (timeSettingDto == null) {
			return list;
		}
		// 勤怠集計情報に値を設定
		dto.setWorkTime(getRoundMinute(workTime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		dto.setSpecificWorkTime(getRoundMinute(specificWorkTime, timeSettingDto.getRoundMonthlyWork(), timeSettingDto
			.getRoundMonthlyWorkUnit()));
		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.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.setLegalCompensationOccurred(legalCompensationOccurred);
		dto.setSpecificCompensationOccurred(specificCompensationOccurred);
		dto.setLateCompensationOccurred(lateCompensationOccurred);
		dto.setLegalCompensationUnused(legalCompensationUnused);
		dto.setSpecificCompensationUnused(specificCompensationUnused);
		dto.setLateCompensationUnused(lateCompensationUnused);
		// 集計時エラー内容リスト確認
		if (list.isEmpty() == false) {
			return list;
		}
		// 集計時エラー内容リスト及び登録要否確認
		if (list.isEmpty() && needRegist) {
			// 勤怠集計データ登録
			totalTimeRegist.regist(dto);
		}
		return list;
	}
	
	/**
	 * 所定勤務時間を取得する。<br>
	 * @param dto 対象DTO
	 * @return 所定勤務時間
	 */
	protected int getSpecificWorkTime(AttendanceDtoInterface dto) {
		return dto.getWorkTime() - dto.getOvertime() - dto.getLegalWorkTime();
	}
	
	/**
	 * 特別休暇の集計をする。<br>
	 * @param personalId 対象個人ID
	 * @param needRegist 登録要否(true：登録要、false：登録不要)
	 * @return 特別休暇回数
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected double calcToalLeave(String personalId, boolean needRegist) throws MospException {
		// 特別休暇回数準備
		double totalLeave = 0D;
		// 特別休暇集計データ削除
		if (needRegist) {
			totalLeaveRegist.delete(personalId, calculationYear, calculationMonth);
		}
		// 休暇種別マスタ毎に処理
		for (HolidayDtoInterface holidayDto : specialHolidayList) {
			// 休暇種別マスタ毎の休暇回数を取得
			double times = calcHoliday(personalId, TimeConst.CODE_HOLIDAYTYPE_SPECIAL, holidayDto.getHolidayCode());
			// 特別休暇回数に加算
			totalLeave += times;
			// 登録要否確認
			if (needRegist == false) {
				continue;
			}
			// 特別休暇集計データ登録
			TotalLeaveDtoInterface dto = totalLeaveRegist.getInitDto();
			dto.setPersonalId(personalId);
			dto.setCalculationYear(calculationYear);
			dto.setCalculationMonth(calculationMonth);
			dto.setHolidayCode(holidayDto.getHolidayCode());
			dto.setTimes(times);
			totalLeaveRegist.insert(dto);
			
		}
		return totalLeave;
	}
	
	/**
	 * その他休暇の集計をする。<br>
	 * @param personalId 対象個人ID
	 * @param needRegist 登録要否(true：登録要、false：登録不要)
	 * @return その他休暇回数
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected double calcTotalOtherVacation(String personalId, boolean needRegist) throws MospException {
		// その他休暇回数準備
		double totalOtherVacation = 0D;
		// その他休暇集計データ削除
		if (needRegist) {
			totalOtherVacationRegist.delete(personalId, calculationYear, calculationMonth);
		}
		// 休暇種別マスタ毎に処理
		for (HolidayDtoInterface holidayDto : otherHolidayList) {
			// 休暇種別マスタ毎の休暇回数を取得
			double times = calcHoliday(personalId, TimeConst.CODE_HOLIDAYTYPE_OTHER, holidayDto.getHolidayCode());
			// その他休暇回数に加算
			totalOtherVacation += times;
			// 登録要否確認
			if (needRegist == false) {
				continue;
			}
			// その他休暇集計データ登録
			TotalOtherVacationDtoInterface dto = totalOtherVacationRegist.getInitDto();
			dto.setPersonalId(personalId);
			dto.setCalculationYear(calculationYear);
			dto.setCalculationMonth(calculationMonth);
			dto.setHolidayCode(holidayDto.getHolidayCode());
			dto.setTimes(times);
			totalOtherVacationRegist.insert(dto);
		}
		return totalOtherVacation;
	}
	
	/**
	 * 欠勤の集計をする。<br>
	 * @param personalId 対象個人ID
	 * @param needRegist 登録要否(true：登録要、false：登録不要)
	 * @return 欠勤回数
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected double calcTotalAbsence(String personalId, boolean needRegist) throws MospException {
		// 欠勤回数準備
		double totalAbsence = 0D;
		// 欠勤集計データ削除
		if (needRegist) {
			totalAbsenceRegist.delete(personalId, calculationYear, calculationMonth);
		}
		// 休暇種別マスタ毎に処理
		for (HolidayDtoInterface holidayDto : absenceList) {
			// 休暇種別マスタ毎の休暇回数を取得
			double times = calcHoliday(personalId, TimeConst.CODE_HOLIDAYTYPE_ABSENCE, holidayDto.getHolidayCode());
			// 欠勤回数に加算
			totalAbsence += times;
			// 登録要否確認
			if (needRegist == false) {
				continue;
			}
			// 欠勤集計データ登録
			TotalAbsenceDtoInterface dto = totalAbsenceRegist.getInitDto();
			dto.setPersonalId(personalId);
			dto.setCalculationYear(calculationYear);
			dto.setCalculationMonth(calculationMonth);
			dto.setAbsenceCode(holidayDto.getHolidayCode());
			dto.setTimes(times);
			totalAbsenceRegist.insert(dto);
		}
		return totalAbsence;
	}
	
	/**
	 * 休暇回数を取得する。<br>
	 * {@link TotalTimeCalcBean#holidayRequestDtoList}から対象休暇種別コードの
	 * 休暇申請情報を取得し、承認完了の申請をカウントする。<br>
	 * @param personalId  対象個人ID
	 * @param holidayType 対象休暇区分
	 * @param holidayCode 対象休暇種別コード
	 * @return 休暇回数
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected double calcHoliday(String personalId, int holidayType, String holidayCode) throws MospException {
		// 回数準備
		double times = 0;
		// 締期間(対象日)内の日毎に処理
		for (Date date : targetDateList) {
			// 勤務形態取得
			String workTypeCode = getScheduleWorkTypeCode(personalId, date, true);
			// 勤務形態確認
			if (workTypeCode == null || workTypeCode.isEmpty()) {
				// 勤務形態が取得できない場合
				continue;
			}
			if (TimeConst.CODE_HOLIDAY_LEGAL_HOLIDAY.equals(workTypeCode)
					|| TimeConst.CODE_HOLIDAY_PRESCRIBED_HOLIDAY.equals(workTypeCode)) {
				// 法定休日又は所定休日の場合
				continue;
			}
			List<HolidayRequestDtoInterface> list = getHolidayRequestDtoList(date, holidayType, holidayCode);
			// 休暇申請毎に処理
			for (HolidayRequestDtoInterface holidayRequestDto : list) {
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(holidayRequestDto.getWorkflow());
				if (workflowDto == null) {
					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 += TimeConst.HOLIDAY_TIMES_HALF;
					}
				}
			}
		}
		return times;
	}
	
	/**
	 * 手当集計。
	 * @param personalId 個人ID
	 * @param calculationYear 年
	 * @param calculationMonth 月
	 * @param cutoffCode 締日コード
	 * @param allowanceCode 手当コード
	 * @return 手当集計データ
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected TotalAllowanceDtoInterface calcTotalAllowance(String personalId, int calculationYear,
			int calculationMonth, String cutoffCode, String allowanceCode) throws MospException {
		// 回数準備
		int times = 0;
		// 締期間で手当情報リストを取得
		List<AllowanceDtoInterface> list = allowanceDao.findForList(personalId, allowanceCode, personalFirstDate,
				personalLastDate);
		// 手当情報毎に処理
		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 {
		// 締日情報取得
		CutoffDtoInterface cutoff = cutoffUtil.getCutoffForPersonalId(personalId, year, month);
		// 処理結果確認(締日が取得できなかった場合)
		if (mospParams.hasErrorMessage()) {
			return TimeConst.CODE_NOT_APPROVED_NONE;
		}
		// 計算情報設定
		setCalculationInfo(year, month, cutoff.getCutoffCode());
		// 処理結果確認(集計クラス計算情報設定に失敗した場合)
		if (mospParams.hasErrorMessage()) {
			return TimeConst.CODE_NOT_APPROVED_NONE;
		}
		// 締期間初日(個人)設定
		personalFirstDate = getPersonalFirstDate(personalId);
		// 締期間最終日(個人)設定
		personalLastDate = getPersonalLastDate(personalId);
		// 締期間(個人)確認
		if (personalFirstDate == null || personalLastDate == null) {
			return TimeConst.CODE_NOT_APPROVED_NONE;
		}
		// 個人計算情報設定
		setPersonalInfo(personalId);
		// 処理結果確認
		if (mospParams.hasErrorMessage()) {
			return TimeConst.CODE_NOT_APPROVED_NONE;
		}
		// 勤怠
		for (AttendanceDtoInterface attendanceDto : attendanceDtoList) {
			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;
			}
		}
		// 残業
		for (OvertimeRequestDtoInterface requestDto : overtimeRequestDtoList) {
			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;
			}
		}
		// 休暇
		for (HolidayRequestDtoInterface requestDto : holidayRequestDtoList) {
			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;
			}
		}
		// 休日出勤
		for (WorkOnHolidayRequestDtoInterface requestDto : workOnHolidayRequestDtoList) {
			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;
			}
		}
		// 代休
		for (SubHolidayRequestDtoInterface requestDto : subHolidayRequestDtoList) {
			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;
			}
		}
		// 時差出勤
		for (DifferenceRequestDtoInterface requestDto : differenceRequestDtoList) {
			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 人事マスタDTOクラス
	 * @return エラーリスト
	 */
	protected CutoffErrorListDtoInterface getCutoffErrorListDto(Date date, HumanDtoInterface humanDto) {
		CutoffErrorListDtoInterface cutoffErrorListDto = new CutoffErrorListDto();
		cutoffErrorListDto.setDate(date);
		cutoffErrorListDto.setEmployeeCode(humanDto.getEmployeeCode());
		cutoffErrorListDto.setPersonalId(humanDto.getPersonalId());
		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>
	 * 対象個人IDが入社していない場合は、nullを返す。<br>
	 * @param personalId 対象個人ID
	 * @return 締期間初日(個人)
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected Date getPersonalFirstDate(String personalId) throws MospException {
		// 入社日取得
		EntranceDtoInterface entranceDto = entranceDao.findForInfo(personalId);
		// 入社日確認
		if (entranceDto == null) {
			return null;
		}
		// 締期間初日が入社日よりも前の場合
		if (cutoffFirstDate.before(entranceDto.getEntranceDate())) {
			// 入社日を取得
			return entranceDto.getEntranceDate();
		}
		return cutoffFirstDate;
	}
	
	/**
	 * 締期間最終日(個人)を取得する。<br>
	 * 対象個人IDの退社日が締期間最終日よりも前の場合は、退社日を取得する。<br>
	 * @param personalId 対象個人ID
	 * @return 締期間最終日(個人)
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected Date getPersonalLastDate(String personalId) throws MospException {
		// 退社日取得
		RetirementDtoInterface retirementDto = retirementDao.findForInfo(personalId);
		// 退社日確認
		if (retirementDto == null) {
			return cutoffLastDate;
		}
		// 締期間最終日が退社日よりも後の場合
		if (cutoffLastDate.after(retirementDto.getRetirementDate())) {
			return retirementDto.getRetirementDate();
		}
		return cutoffLastDate;
	}
	
	/**
	 * カレンダ日情報群を取得する。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}及び
	 * {@link TotalTimeCalcBean#setPersonalInfo(String)}で設定された情報を基に、
	 * 対象個人IDのカレンダ日情報群を作成する。<br>
	 * 対象日において設定適用情報が取得できない場合は、
	 * 対象日のカレンダ日情報にnullを設定する。
	 * @param personalId 対象個人ID
	 * @return カレンダ日情報群
	 * @throws MospException カレンダ日情報の取得に失敗した場合
	 */
	protected Map<Date, ScheduleDateDtoInterface> getScheduleMap(String personalId) throws MospException {
		// カレンダ日情報郡準備
		Map<Date, ScheduleDateDtoInterface> map = new HashMap<Date, ScheduleDateDtoInterface>();
		// 締期間(対象日)内の日毎に処理
		for (Date targetDate : targetDateList) {
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = applicationMap.get(targetDate);
			// 設定適用情報が取得できない場合
			if (applicationDto == null) {
				// カレンダ日情報追加
				map.put(targetDate, null);
				continue;
			}
			// カレンダ日情報取得
			ScheduleDateDtoInterface scheduleDateDto = scheduleDateDao.findForInfo(applicationDto.getScheduleCode(),
					targetDate, targetDate);
			// カレンダ日情報確認
			scheduleDate.chkExistScheduleDate(scheduleDateDto, targetDate);
			if (mospParams.hasErrorMessage()) {
				break;
			}
			// カレンダ日情報追加
			map.put(targetDate, scheduleDateDto);
		}
		return map;
	}
	
	/**
	 * 振替休日情報群を取得する。<br>
	 * {@link TotalTimeCalcBean#setCalculationInfo(int, int, String)}及び
	 * {@link TotalTimeCalcBean#setPersonalInfo(String)}で設定された情報を基に、
	 * 対象個人IDの承認済振替休日情報群を作成する。<br>
	 * 但し、承認済であり、振替範囲が全休のもののみを取得対象とする。<br>
	 * @param personalId 対象個人ID
	 * @return 振替休日情報群
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	protected Map<Date, SubstituteDtoInterface> getSubstituteMap(String personalId) throws MospException {
		// 振替休日情報群準備
		Map<Date, SubstituteDtoInterface> map = new HashMap<Date, SubstituteDtoInterface>();
		// 締期間(対象日)内の日毎に処理
		for (Date targetDate : targetDateList) {
			// 振替休日情報リスト取得
			List<SubstituteDtoInterface> list = substituteDao.findForList(personalId, targetDate);
			// 振替休日毎に処理
			for (SubstituteDtoInterface substituteDto : list) {
				// 振替範囲確認
				if (substituteDto.getSubstituteRange() != TimeConst.CODE_HOLIDAY_RANGE_ALL) {
					// 全休でなければ対象外
					continue;
				}
				// ワークフロー番号からワークフロー情報を取得
				WorkflowDtoInterface workflowDto = workflowDao.findForKey(substituteDto.getWorkflow());
				if (workflowDto == null) {
					continue;
				}
				// もし承認済ならば
				if (PlatformConst.CODE_STATUS_COMPLETE.equals(workflowDto.getWorkflowStatus())) {
					// 振替休日情報追加
					map.put(targetDate, substituteDto);
				}
			}
		}
		return map;
	}
	
	/**
	 * カレンダの勤務形態コードを取得する。<br>
	 * カレンダが取得できない場合はnullを返す。<br>
	 * @param personalId    個人ID
	 * @param targetDate    対象日
	 * @param useSubstitute 振替休日情報考慮要否
	 * @return 勤務形態コード
	 * @throws MospException インスタンスの取得、或いはSQL実行に失敗した場合
	 */
	private String getScheduleWorkTypeCode(String personalId, Date targetDate, boolean useSubstitute)
			throws MospException {
		// 振替休日情報考慮要否確認
		if (useSubstitute) {
			// 振替休日情報取得
			SubstituteDtoInterface substituteDto = substituteMap.get(targetDate);
			// 振替休日情報確認
			if (substituteDto != null) {
				// 振替休日情報の休暇種別を取得
				return substituteDto.getSubstituteType();
			}
		}
		// カレンダ存在確認
		if (scheduleMap.get(targetDate) == null) {
			return null;
		}
		// 勤務形態コード
		return scheduleMap.get(targetDate).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;
	}
	
	/**
	 * 残業申請チェック。<br>
	 * @param list リスト
	 * @param attendanceDto 勤怠DTO
	 * @param humanDto 人事マスタDTO
	 * @param amHoliday 午前休フラグ
	 * @param pmHoliday 午後休フラグ
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void checkOvertimeRequest(List<CutoffErrorListDtoInterface> list, AttendanceDtoInterface attendanceDto,
			HumanDtoInterface humanDto, boolean amHoliday, boolean pmHoliday) throws MospException {
		if (attendanceDto.getOvertimeAfter() > 0) {
			// 後残業がある場合
			OvertimeRequestDtoInterface overtimeRequestDto = overtimeRequestDao.findForKeyOnWorkflow(attendanceDto
				.getPersonalId(), attendanceDto.getWorkDate(), 2);
			if (overtimeRequestDto == null) {
				CutoffErrorListDtoInterface cutoffErrorListDto = getCutoffErrorListDto(attendanceDto.getWorkDate(),
						humanDto);
				cutoffErrorListDto.setType("残業");
				cutoffErrorListDto.setState("未申請");
				list.add(cutoffErrorListDto);
			}
		}
	}
	
	/**
	 * 週の終了曜日を取得する。<br>
	 * @param startDayOfWeek 週の開始曜日を示すフィールド値
	 * @return 週の終了曜日を示すフィールド値
	 */
	private int getEndDayOfWeek(int startDayOfWeek) {
		if (startDayOfWeek == Calendar.SUNDAY) {
			// 週の開始曜日が日曜日の場合
			return Calendar.SATURDAY;
		}
		return --startDayOfWeek;
	}
	
	/**
	 * 配列取得
	 * @param is 対象
	 * @return 配列
	 */
	private int[] getIntArray(int... is) {
		return is;
	}
	
}
