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

import jp.mosp.framework.base.MospException;
import jp.mosp.framework.base.MospParams;
import jp.mosp.framework.utils.DateUtility;
import jp.mosp.platform.bean.human.impl.HumanSearchBean;
import jp.mosp.platform.constant.PlatformConst;
import jp.mosp.platform.dto.human.HumanDtoInterface;
import jp.mosp.time.bean.CutoffReferenceBeanInterface;
import jp.mosp.time.bean.TimeSettingReferenceBeanInterface;
import jp.mosp.time.bean.TotalTimeCorrectionReferenceBeanInterface;
import jp.mosp.time.bean.TotalTimeSearchBeanInterface;
import jp.mosp.time.dao.settings.TotalTimeDataDaoInterface;
import jp.mosp.time.dto.settings.ApplicationDtoInterface;
import jp.mosp.time.dto.settings.CutoffDtoInterface;
import jp.mosp.time.dto.settings.SubordinateListDtoInterface;
import jp.mosp.time.dto.settings.TotalTimeCorrectionDtoInterface;
import jp.mosp.time.dto.settings.TotalTimeDataDtoInterface;
import jp.mosp.time.dto.settings.impl.SubordinateListDto;
import jp.mosp.time.utils.TimeUtility;

/**
 * 勤怠集計結果検索クラス。
 */
public class TotalTimeSearchBean extends HumanSearchBean implements TotalTimeSearchBeanInterface {
	
	/**
	 * 勤怠集計データDAO。
	 */
	private TotalTimeDataDaoInterface					totalTimeDataDao;
	
	/**
	 * 勤怠集計修正情報参照。
	 */
	private TotalTimeCorrectionReferenceBeanInterface	totalTimeCorrection;
	
	/**
	 * 勤怠設定参照クラス。
	 */
	private TimeSettingReferenceBeanInterface			timeSettingReference;
	
	/**
	 * 設定適用管理検索DAO。
	 */
	private ApplicationReferenceBean					applicationReference;
	
	/**
	 * 勤怠集計クラス。
	 */
	private TotalTimeCalcBean							totalTimeCalcBean;
	
	/**
	 * 締日マスタ参照クラス。
	 */
	private CutoffReferenceBeanInterface				cutoffReference;
	
	/**
	 * 未承認。
	 */
	private String										approval;
	
	/**
	 * 未集計。
	 */
	private String										calc;
	
	/**
	 * 締日コード。
	 */
	private String										cutoffCode;
	

	/**
	 * コンストラクタ。
	 */
	public TotalTimeSearchBean() {
		// 処理無し
	}
	
	/**
	 * コンストラクタ。
	 * @param mospParams MosPパラメータクラス。
	 * @param connection DBコネクション。
	 */
	public TotalTimeSearchBean(MospParams mospParams, Connection connection) {
		super(mospParams, connection);
	}
	
	@Override
	public void initBean() throws MospException {
		// 継承元の処理を実施
		super.initBean();
		// 勤怠集計データDAO取得
		totalTimeDataDao = (TotalTimeDataDaoInterface)createDao(TotalTimeDataDaoInterface.class);
		// 勤怠集計修正情報参照クラス取得
		totalTimeCorrection = (TotalTimeCorrectionReferenceBeanInterface)createBean(TotalTimeCorrectionReferenceBeanInterface.class);
		// 勤怠設定管理DAO
		timeSettingReference = (TimeSettingReferenceBeanInterface)createBean(TimeSettingReferenceBeanInterface.class);
		// 設定適用管理検索DAO。
		applicationReference = (ApplicationReferenceBean)createBean(ApplicationReferenceBean.class);
		// 勤怠集計クラス
		totalTimeCalcBean = (TotalTimeCalcBean)createBean(TotalTimeCalcBean.class);
		// 締日マスタ参照クラス
		cutoffReference = (CutoffReferenceBeanInterface)createBean(CutoffReferenceBeanInterface.class);
	}
	
	@Override
	public List<SubordinateListDtoInterface> getSearchList() throws MospException {
		// 勤怠集計結果リスト準備
		List<SubordinateListDtoInterface> list = new ArrayList<SubordinateListDtoInterface>();
		// 締日情報取得
		CutoffDtoInterface cutoffDto = cutoffReference.getCutoffInfo(cutoffCode, targetDate);
		// 検索年月取得
		int targetYear = DateUtility.getYear(targetDate);
		int targetMonth = DateUtility.getMonth(targetDate);
		// 人事マスタ情報検索条件設定(日付)
		setTargetDate(TimeUtility.getCutoffLastDate(cutoffDto.getCutoffDate(), targetYear, targetMonth));
		setStartDate(TimeUtility.getCutoffFirstDate(cutoffDto.getCutoffDate(), targetYear, targetMonth));
		setEndDate(TimeUtility.getCutoffLastDate(cutoffDto.getCutoffDate(), targetYear, targetMonth));
		// 人事マスタ情報検索条件設定
		setEmployeeCodeType(PlatformConst.SEARCH_FORWARD_MATCH);
		setStateType(PlatformConst.EMPLOYEE_STATE_PRESENCE);
		// 人事マスタ情報検索条件から締日の対象となる人事情報のリストを取得
		List<HumanDtoInterface> humanList = getCutoffHumanList(search());
		// 人事情報毎に処理
		for (HumanDtoInterface human : humanList) {
			// 勤怠集計結果情報準備
			SubordinateListDtoInterface dto = new SubordinateListDto();
			// 勤怠集計情報取得
			TotalTimeDataDtoInterface totalTimeDataDto = totalTimeDataDao.findForKey(human.getPersonalId(), targetYear,
					targetMonth);
			if (totalTimeDataDto == null) {
				if ("2".equals(calc)) {
					// 仮締の場合
					continue;
				}
				// 締状態
				dto.setCalc(mospParams.getName("Ram") + mospParams.getName("Cutoff"));
			} else {
				if ("1".equals(calc)) {
					// 未締の場合
					continue;
				}
				// 出勤日数の取得
				dto.setWorkDate(totalTimeDataDto.getTimesWorkDate());
				// 勤務時間の取得
				dto.setWorkTime(totalTimeDataDto.getWorkTime());
				// 休憩時間の取得
				dto.setRestTime(totalTimeDataDto.getRestTime());
				// 遅刻時間の取得
				dto.setLateTime(totalTimeDataDto.getLateTime());
				// 早退時間の取得
				dto.setLeaveEarlyTime(totalTimeDataDto.getLeaveEarlyTime());
				// 残業時間の取得
				dto.setOverTimeIn(totalTimeDataDto.getOvertimeIn());
				// 法定外残業時間の取得
				dto.setOverTimeOut(totalTimeDataDto.getOvertimeOut());
				// 休出時間の取得
				dto.setWorkOnHolidayTime(totalTimeDataDto.getWorkOnHoliday()
						+ totalTimeDataDto.getWorkOnSpecificHoliday());
				// 深夜時間の取得
				dto.setLateNightTime(totalTimeDataDto.getLateNight());
				// 有休日数の取得
				dto.setPaidHoliday(totalTimeDataDto.getTimesPaidHoliday());
				// 休暇日数の取得
				dto.setAllHoliday(totalTimeDataDto.getTotalSpecialHoliday() + totalTimeDataDto.getTotalOtherHoliday());
				// 欠勤日数の取得
				dto.setAbsence(totalTimeDataDto.getTotalAbsence());
				// 締状態
				dto.setCalc(mospParams.getName("Provisional") + mospParams.getName("Cutoff"));
			}
			// 未承認
			String approvalStatus = totalTimeCalcBean.getApprovalStatus(human.getPersonalId(), DateUtility
				.getYear(targetDate), DateUtility.getMonth(targetDate));
			if (mospParams.hasErrorMessage()) {
				return list;
			}
			if (approvalStatus == null) {
				continue;
			}
			if ("0".equals(approvalStatus)) {
				// 未承認なしの場合
				if ("1".equals(approval)) {
					continue;
				}
				dto.setApproval(mospParams.getName("Without"));
			}
			if ("1".equals(approvalStatus)) {
				// 未承認ありの場合
				if ("0".equals(approval)) {
					continue;
				}
				dto.setApproval(mospParams.getName("Yes"));
			}
			dto.setCorrection("");
			// 勤怠集計修正情報取得
			TotalTimeCorrectionDtoInterface totalTimeCorrectionDto = totalTimeCorrection
				.getLatestTotalTimeCorrectionInfo(human.getPersonalId(), DateUtility.getYear(targetDate), DateUtility
					.getMonth(targetDate));
			// 勤怠集計修正情報確認
			if (totalTimeCorrectionDto != null) {
				if (totalTimeCorrectionDto.getCorrectionPersonalId().equals(human.getPersonalId())) {
					dto.setCorrection(mospParams.getName("CorrectionHistory"));
				} else {
					dto.setCorrection(mospParams.getName("Other"));
				}
			}
			// 個人ID取得
			dto.setPersonalId(human.getPersonalId());
			// 社員コードの取得
			dto.setEmployeeCode(human.getEmployeeCode());
			// 社員名の取得
			dto.setLastName(human.getLastName());
			dto.setFirstName(human.getFirstName());
			// 所属の取得
			dto.setSectionCode(human.getSectionCode());
			list.add(dto);
		}
		return list;
	}
	
	/**
	 * 締日の対象となる人事情報のリストを取得する。<br>
	 * 設定された締日コード及び対象日を用いて、対象人事情報が適用される設定を取得し、
	 * 締日の対象となる人事情報のリストを作成する。<br>
	 * @param humanList  対象人事情報リスト
	 * @return 締日の対象となる人事情報のリスト
	 * @throws MospException 勤怠設定情報或いは設定適用情報の取得に失敗した場合
	 */
	protected List<HumanDtoInterface> getCutoffHumanList(List<HumanDtoInterface> humanList) throws MospException {
		// 締日の対象となる人事情報のリストを準備
		List<HumanDtoInterface> cutoffHumanList = new ArrayList<HumanDtoInterface>();
		// 勤怠設定情報リスト取得
		List<String> workSettingCodeList = timeSettingReference.getWorkSettingCode(cutoffCode, targetDate);
		// 勤怠設定情報リスト確認
		if (workSettingCodeList.isEmpty()) {
			// 締日が設定されている勤怠設定情報が存在しない場合
			return cutoffHumanList;
		}
		// 検索年月取得
		int targetYear = DateUtility.getYear(targetDate);
		int targetMonth = DateUtility.getMonth(targetDate);
		// 対象人事情報毎に処理
		for (HumanDtoInterface humanDto : humanList) {
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = applicationReference.findForMonth(humanDto.getPersonalId(),
					targetYear, targetMonth);
			// 設定適用情報確認
			if (applicationDto == null) {
				continue;
			}
			// 勤怠設定コード確認
			if (workSettingCodeList.contains(applicationDto.getWorkSettingCode())) {
				// 締日の対象となる人事情報のリストに追加
				cutoffHumanList.add(humanDto);
			}
		}
		return cutoffHumanList;
	}
	
	@Override
	public void setApproval(String approval) {
		this.approval = approval;
	}
	
	@Override
	public void setCalc(String calc) {
		this.calc = calc;
	}
	
	@Override
	public void setCutoffCode(String cutoffCode) {
		this.cutoffCode = cutoffCode;
	}
	
}
