/*
 * MosP - Mind Open Source Project    http://www.mosp.jp/
 * Copyright (C) MIND Co., Ltd.       http://www.e-mind.co.jp/
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package jp.mosp.time.bean.impl;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jp.mosp.framework.base.MospException;
import jp.mosp.framework.base.MospParams;
import jp.mosp.framework.constant.MospConst;
import jp.mosp.framework.utils.DateUtility;
import jp.mosp.platform.base.PlatformBean;
import jp.mosp.platform.bean.human.impl.HumanSearchBean;
import jp.mosp.platform.bean.system.PlatformMasterBeanInterface;
import jp.mosp.platform.bean.workflow.WorkflowIntegrateBeanInterface;
import jp.mosp.platform.constant.PlatformConst;
import jp.mosp.platform.dto.human.HumanDtoInterface;
import jp.mosp.platform.dto.workflow.RouteApplicationDtoInterface;
import jp.mosp.platform.utils.MonthUtility;
import jp.mosp.platform.utils.PlatformUtility;
import jp.mosp.time.bean.AttendanceReferenceBeanInterface;
import jp.mosp.time.bean.HolidayRequestReferenceBeanInterface;
import jp.mosp.time.bean.PaidHolidayInfoReferenceBeanInterface;
import jp.mosp.time.bean.StockHolidayInfoReferenceBeanInterface;
import jp.mosp.time.bean.SubordinateFiscalSearchBeanInterface;
import jp.mosp.time.bean.TimeMasterBeanInterface;
import jp.mosp.time.bean.TotalTimeCalcBeanInterface;
import jp.mosp.time.bean.TotalTimeReferenceBeanInterface;
import jp.mosp.time.constant.TimeConst;
import jp.mosp.time.dao.settings.HolidayDataDaoInterface;
import jp.mosp.time.dto.settings.ApplicationDtoInterface;
import jp.mosp.time.dto.settings.AttendanceDtoInterface;
import jp.mosp.time.dto.settings.HolidayDataDtoInterface;
import jp.mosp.time.dto.settings.HolidayRequestDtoInterface;
import jp.mosp.time.dto.settings.SubordinateFiscalListDtoInterface;
import jp.mosp.time.dto.settings.TotalTimeDataDtoInterface;
import jp.mosp.time.dto.settings.impl.SubordinateFiscalListDto;

/**
 * 統計情報一覧検索クラス。<br>
 */
public class SubordinateFiscalSearchBean extends HumanSearchBean implements SubordinateFiscalSearchBeanInterface {
	
	/**
	 * 勤怠情報参照クラス。<br>
	 */
	protected TotalTimeCalcBeanInterface				totalTimeCalc;
	
	/**
	 * ワークフロー統合クラス。<br>
	 */
	protected WorkflowIntegrateBeanInterface			workflowIntegrate;
	
	/**
	 * プラットフォームマスタ参照クラス。<br>
	 */
	protected PlatformMasterBeanInterface				platformMaster;
	
	/**
	 * 勤怠集計データ登録クラス。<br>
	 */
	protected TotalTimeReferenceBeanInterface			totalTimeRefer;
	
	/**
	 * 有給休暇情報参照クラス。<br>
	 */
	protected PaidHolidayInfoReferenceBeanInterface		paidHolidayInfo;
	
	/**
	 * ストック情報参照クラス。<br>
	 */
	protected StockHolidayInfoReferenceBeanInterface	stockHolidayInfo;
	
	/**
	 * 休暇申請情報参照クラス。<br>
	 */
	protected HolidayRequestReferenceBeanInterface		holidayRequestRefer;
	
	/**
	 * 休暇データDAOクラス。<br>
	 */
	protected HolidayDataDaoInterface					holidayDataDao;
	
	/**
	 * 勤怠情報参照クラス。<br>
	 */
	protected AttendanceReferenceBeanInterface			attendanceRefer;
	
	/**
	 * 勤怠関連マスタ参照クラス。<br>
	 */
	protected TimeMasterBeanInterface					timeMaster;
	
	/**
	 * 表示年度。
	 */
	protected int										displayYear;
	
	/**
	 * 対象年。
	 */
	protected int										targetYear;
	
	/**
	 * 対象月。
	 */
	protected int										targetMonth;
	
	/**
	 * 社員区分。
	 */
	protected String									humanType;
	
	/**
	 * 検索区分：承認すべき申請者
	 */
	protected String									TYPE_APPLICANTS_APPROVE	= "1";
	
	/**
	 * 検索区分：部下
	 */
	protected String									TYPE_SUBORDINATE		= "2";
	
	
	/**
	 * コンストラクタ。
	 */
	public SubordinateFiscalSearchBean() {
		// 処理無し
	}
	
	@Override
	public void initBean() throws MospException {
		super.initBean();
		// 勤怠集計クラス
		totalTimeCalc = (TotalTimeCalcBeanInterface)createBean(TotalTimeCalcBeanInterface.class);
		// ワークフロー統合クラス
		workflowIntegrate = (WorkflowIntegrateBeanInterface)createBean(WorkflowIntegrateBeanInterface.class);
		// プラットフォームマスタ参照クラス
		platformMaster = (PlatformMasterBeanInterface)createBean(PlatformMasterBeanInterface.class);
		// 有給休暇情報参照クラス
		paidHolidayInfo = (PaidHolidayInfoReferenceBeanInterface)createBean(
				PaidHolidayInfoReferenceBeanInterface.class);
		// ストック情報参照クラス
		stockHolidayInfo = (StockHolidayInfoReferenceBeanInterface)createBean(
				StockHolidayInfoReferenceBeanInterface.class);
		// 休暇申請情報参照クラス
		holidayRequestRefer = (HolidayRequestReferenceBeanInterface)createBean(
				HolidayRequestReferenceBeanInterface.class);
		// 休暇情報DAOクラス
		holidayDataDao = (HolidayDataDaoInterface)createDao(HolidayDataDaoInterface.class);
		// 勤怠集計参照クラス
		totalTimeRefer = (TotalTimeReferenceBeanInterface)createBean(TotalTimeReferenceBeanInterface.class);
		// 勤怠参照クラス
		attendanceRefer = (AttendanceReferenceBeanInterface)createBean(AttendanceReferenceBeanInterface.class);
		// 勤怠関連マスタ参照クラス
		timeMaster = (TimeMasterBeanInterface)createBean(TimeMasterBeanInterface.class);
		// 有給休暇情報参照クラスに勤怠関連マスタ参照クラスを設定
		paidHolidayInfo.setTimeMasterBean(timeMaster);
	}
	
	/**
	 * {@link PlatformBean#PlatformBean(MospParams, Connection)}を実行する。<br>
	 * @param mospParams MosP処理情報
	 * @param connection DBコネクション
	 */
	public SubordinateFiscalSearchBean(MospParams mospParams, Connection connection) {
		super(mospParams, connection);
	}
	
	@Override
	public List<SubordinateFiscalListDtoInterface> getSubordinateFiscalList() throws MospException {
		// 検索結果リスト準備
		List<HumanDtoInterface> resultList = new ArrayList<HumanDtoInterface>();
		// 検索条件設定(検索区分(社員コード))
		setEmployeeCodeType(PlatformConst.SEARCH_FORWARD_MATCH);
		// 検索条件(部下)設定
		setSubordinateParams();
		// 検索条件が空白の場合
		if (humanType.isEmpty()) {
			// 部下検索リスト取得
			resultList = search();
			// 検索条件再設定(操作区分)(承認対象者全員が検索対象となるためnullを設定)
			setOperationType(null);
			// 全社員検索リスト取得
			List<HumanDtoInterface> humanList = search();
			// 承認できる社員個人ID群取得
			List<HumanDtoInterface> approvalList = getApprovaleForApplicantList(humanList);
			// 個人IDセットを取得
			Set<String> resultSet = PlatformUtility.getPersonalIdSet(resultList);
			// 部下検索リスト毎に処理
			for (HumanDtoInterface humanDto : approvalList) {
				// 部下検索リストに承認できる社員個人IDが含まれている場合
				if (resultSet.contains(humanDto.getPersonalId())) {
					continue;
				}
				// 検索結果リストに追加
				resultList.add(humanDto);
			}
		}
		// 検索条件が承認すべき申請者の場合
		if (humanType.equals(TYPE_APPLICANTS_APPROVE)) {
			// 検索条件再設定(操作区分)(承認対象者全員が検索対象となるためnullを設定)
			setOperationType(null);
			// 検索結果リスト人事情報検索追加
			List<HumanDtoInterface> humanList = search();
			// 承認できる社員個人ID群取得
			resultList = getApprovaleForApplicantList(humanList);
		}
		// 検索条件が部下の場合
		if (humanType.equals(TYPE_SUBORDINATE)) {
			// 検索結果リスト人事情報検索追加
			resultList = search();
		}
		// 部下一覧情報リスト取得
		return subordinateFiscalList(resultList);
	}
	
	/**
	 * 人事情報リストを基に、統計情報リストを取得する。<br>
	 * <br>
	 * <br>
	 * @param humanList 人事情報リスト
	 * @return 部下一覧情報リスト
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	public List<SubordinateFiscalListDtoInterface> subordinateFiscalList(List<HumanDtoInterface> humanList)
			throws MospException {
		// 統計情報リスト準備
		List<SubordinateFiscalListDtoInterface> subordinateFiscalList = new ArrayList<SubordinateFiscalListDtoInterface>();
		// 年度の開始日、終了日取得
		Date firstDate = MonthUtility.getFiscalYearFirstDate(displayYear, mospParams);
		Date lastDate = MonthUtility.getFiscalYearLastDate(displayYear, mospParams);
		// 検索基準開始日、終了日取得
		Date searchEndDate = getEndTargetDate(firstDate, lastDate);
		// エラーメッセージリストを保持
		List<String> errorMessageList = new ArrayList<String>(mospParams.getErrorMessageList());
		// 検索結果から部下一覧リストを作成
		for (HumanDtoInterface humanDto : humanList) {
			// 設定適用判断日付（検索年月最終日）取得
			Date applicationTargetDate = MonthUtility.getYearMonthTermLastDate(targetYear, targetMonth, mospParams);
			// 設定適用情報取得
			ApplicationDtoInterface applicationDto = timeMaster.getApplication(humanDto, applicationTargetDate);
			if (applicationDto == null) {
				continue;
			}
			// 個人IDを取得
			String personalId = humanDto.getPersonalId();
			// 部下年度一覧DTO準備
			SubordinateFiscalListDto dto = new SubordinateFiscalListDto();
			// 年度期間内の勤怠情報リスト取得
			List<AttendanceDtoInterface> attendanceList = attendanceRefer.getAttendanceList(humanDto.getPersonalId(),
					firstDate, lastDate);
			// 勤怠集計マップ取得
			Map<Integer, TotalTimeDataDtoInterface> totalMap = totalTimeRefer.findFiscalMap(personalId, firstDate,
					lastDate);
			if (!attendanceList.isEmpty() || (totalMap != null && !totalMap.isEmpty())) {
				// 残業時間設定
				setOverTime(dto, totalMap, personalId, firstDate);
			} else {
				dto.setOverTime(0);
			}
			// 有休日数設定
			setPaidHoliday(dto, humanDto, displayYear, searchEndDate);
			// ストック日数設定
			setStockHoliday(dto, humanDto, displayYear, searchEndDate);
			// 休暇日数設定
			setHoliday(dto, personalId, firstDate, lastDate);
			
			// 人事情報設定
			setHuman(dto, humanDto);
			// リストに追加
			subordinateFiscalList.add(dto);
		}
		// 保持していたエラーメッセージリストを再設定(検索によるエラーメッセージを除去)
		mospParams.getErrorMessageList().clear();
		mospParams.getErrorMessageList().addAll(errorMessageList);
		// 統計情報リストを取得
		return subordinateFiscalList;
	}
	
	/**
	 * 残業時間を取得し、設定する。<br>
	 * @param dto 統計情報一覧DTO
	 * @param totalMap 勤怠集計マップ
	 * @param personalId 個人ID
	 * @param firstDate 年度初日
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void setOverTime(SubordinateFiscalListDtoInterface dto, Map<Integer, TotalTimeDataDtoInterface> totalMap,
			String personalId, Date firstDate) throws MospException {
		// 値準備
		Integer overTime = 0;
		// 12回処理
		for (int i = 0; i < 12; i++) {
			// 対象日取得
			Date targetDate = DateUtility.addMonth(firstDate, i);
			// 年月取得
			int year = DateUtility.getYear(targetDate);
			int month = DateUtility.getMonth(targetDate);
			// 勤怠集計データを取得
			TotalTimeDataDtoInterface totalTimeDto = totalMap.get(month);
			if (totalTimeDto == null) {
				totalTimeDto = totalTimeCalc.calc(personalId, year, month, false);
			}
			// 残業時間取得
			overTime += totalTimeDto.getOvertime();
		}
		// 残業時間設定
		dto.setOverTime(overTime);
	}
	
	/**
	 * 有給休暇を取得し、設定する。<br>
	 * 下記のいずれかを基準日とする。
	 * ・システム日付が表示年度開始日以前の場合、表示年度開始日。<br>
	 * ・システム日付が表示年度期間内の場合、システム日付。<br>
	 * ・システム日付が表示年度最終日以降の場合、表示年度最終日。<br>
	 * @param dto         統計情報一覧DTO
	 * @param humanDto    人事基本情報
	 * @param displayYear 表示年度
	 * @param targetDate  表示期間対象日
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void setPaidHoliday(SubordinateFiscalListDtoInterface dto, HumanDtoInterface humanDto, int displayYear,
			Date targetDate) throws MospException {
		// 値準備
		double paidHolidayDays = 0.0;
		int paidHolidayTime = 0;
		double paidHolidayRestDays = 0.0;
		int paidHolidayRestTime = 0;
		// 有給休暇申請可能数を取得
		Map<String, Object> map = paidHolidayInfo.getSubordinateFiscalPaidHolidayInfo(humanDto, displayYear,
				targetDate);
		// 時間取得
		int generalWorkHour = ((Integer)map.get("generalWorkHour")).intValue();
		// 有休始(前年度残＋今年度付与)
		paidHolidayDays = ((Double)map.get("currentGiveDay")).doubleValue()
				+ ((Double)map.get("formerRestDay")).doubleValue();
		paidHolidayTime = ((Integer)map.get("currentGiveTime")).intValue()
				+ ((Integer)map.get("formerRestTime")).intValue();
		// 時間単位計算
		if (generalWorkHour > 0) {
			while (paidHolidayTime < 0 && paidHolidayDays >= 1) {
				paidHolidayDays--;
				paidHolidayTime += generalWorkHour;
			}
		}
		// 今年度申請数
		double termUseHolidayRequestDay = ((Double)map.get("termUseHolidayRequestDay")).doubleValue();
		int termUseHolidayRequestTime = ((Integer)map.get("termUseHolidayRequestTime")).intValue();
		// 有休始-有休申請数
		paidHolidayRestDays = paidHolidayDays - termUseHolidayRequestDay;
		paidHolidayRestTime = paidHolidayTime - termUseHolidayRequestTime;
		// 時間単位計算
		if (generalWorkHour > 0) {
			while (paidHolidayRestTime < 0 && paidHolidayRestDays >= 1) {
				paidHolidayRestDays--;
				paidHolidayRestTime += generalWorkHour;
			}
		}
		// 設定
		dto.setPaidHolidayDays(paidHolidayDays);
		dto.setPaidHolidayTime(paidHolidayTime);
		dto.setPaidHolidayRestDays(paidHolidayRestDays);
		dto.setPaidHolidayRestTime(paidHolidayRestTime);
	}
	
	/**
	 * ストック休暇を設定する。<br>
	 * 下記のいずれかを基準日とする。
	 * ・システム日付が表示年度開始日以前の場合、表示年度開始日。<br>
	 * ・システム日付が表示年度期間内の場合、システム日付。<br>
	 * ・システム日付が表示年度最終日以降の場合、表示年度最終日。<br>
	 * @param dto 統計情報
	 * @param humanDto 人事情報
	 * @param displayYear 表示年度
	 * @param targetDate 表示年度最終日
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void setStockHoliday(SubordinateFiscalListDtoInterface dto, HumanDtoInterface humanDto, int displayYear,
			Date targetDate) throws MospException {
		// 値準備
		double stockHolidayDays = 0.0;
		double stockHolidayRestDays = 0.0;
		// 有給休暇申請可能数を取得
		Map<String, Object> map = stockHolidayInfo.getSubordinateFiscalStockHolidayInfo(humanDto, displayYear,
				targetDate);
		// 有休始(前年度残＋今年度付与)
		stockHolidayDays = ((Double)map.get("currentGiveDay")).doubleValue()
				+ ((Double)map.get("formerRestDay")).doubleValue();
		
		// 今年度申請数
		double termUseHolidayRequestDay = ((Double)map.get("termUseHolidayRequestDay")).doubleValue();
		// ストック始-ストック申請数
		stockHolidayRestDays = stockHolidayDays - termUseHolidayRequestDay;
		
		// 設定
		dto.setStockHolidayDays(stockHolidayDays);
		dto.setStockHolidayRestDays(stockHolidayRestDays);
	}
	
	/**
	 * 休暇を統計情報に設定する。<br>
	 * @param dto 統計情報
	 * @param personalId 個人ID
	 * @param firstDate 表示年度開始日
	 * @param lastDate 表示年度最終日
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void setHoliday(SubordinateFiscalListDtoInterface dto, String personalId, Date firstDate, Date lastDate)
			throws MospException {
		// 値準備
		Double holidayDays = 0.0;
		Double holidayRestDays = 0.0;
		// 季節休コード取得
		String seasonCode = mospParams.getApplicationProperty(TimeConst.APP_SHOW_SEASON_HOLIDAY_CODE);
		// 特別休暇リストを取得
		List<HolidayDataDtoInterface> list = holidayDataDao.findPersonTerm(personalId, firstDate, lastDate,
				TimeConst.CODE_HOLIDAYTYPE_SPECIAL);
		// 特別休暇、季節休コード毎に処理
		for (HolidayDataDtoInterface dataDto : list) {
			// コードがXMLで設定した季節休でない場合
			if (!dataDto.getHolidayCode().equals(seasonCode)) {
				continue;
			}
			// 計算
			holidayDays += dataDto.getGivingDay();
			holidayDays -= dataDto.getCancelDay();
		}
		// 休暇申請リスト取得
		List<HolidayRequestDtoInterface> requestList = holidayRequestRefer.getHolidayRequestListOnWorkflow(personalId,
				firstDate, lastDate);
		for (HolidayRequestDtoInterface requestDto : requestList) {
			// 特別休暇でない場合
			if (requestDto.getHolidayType1() != TimeConst.CODE_HOLIDAYTYPE_SPECIAL) {
				continue;
			}
			// 季節休の場合
			if (requestDto.getHolidayType2().equals(seasonCode)) {
				holidayRestDays += requestDto.getUseDay();
			}
		}
		// 設定
		dto.setSeasonHolidayDays(holidayDays);
		dto.setSeasonHolidayRestDays(holidayDays - holidayRestDays);
	}
	
	/**
	 * 人事情報を統計情報に設定する。<br>
	 * @param dto 統計情報
	 * @param humanDto 人事情報
	 */
	public void setHuman(SubordinateFiscalListDtoInterface dto, HumanDtoInterface humanDto) {
		if (humanDto == null) {
			return;
		}
		dto.setPersonalId(humanDto.getPersonalId());
		dto.setEmployeeCode(humanDto.getEmployeeCode());
		dto.setLastName(humanDto.getLastName());
		dto.setFirstName(humanDto.getFirstName());
		dto.setSectionCode(humanDto.getSectionCode());
	}
	
	/**
	 * ログインユーザが承認できる社員の個人IDセット群を取得する。<br>
	 * 対象人事情報リストから承認ルート適用設定情報を取得し、そのルートコードが
	 * 承認対象ルートリストに含まれるかで、被承認者であるかを確認する。<br>
	 * @param humanList 社員リスト
	 * @return ログインユーザが承認者の社員個人ID群
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected List<HumanDtoInterface> getApprovaleForApplicantList(List<HumanDtoInterface> humanList)
			throws MospException {
		// スーパーユーザ権限の場合
		if (mospParams.getUserRole().isSuper()) {
			// 社員リストをそのまま取得(スーパーユーザは全員が承認対象)
			return humanList;
		}
		// 個人IDリスト準備
		List<HumanDtoInterface> list = new ArrayList<HumanDtoInterface>();
		// 承認者がユニットとして登録されているルート群を取得
		Set<String> routeSet = workflowIntegrate.getApproverRouteSet(mospParams.getUser().getPersonalId(), targetDate);
		// 検索人事情報毎に被承認者かどうかを確認して人事情報リストに追加
		for (HumanDtoInterface humanDto : humanList) {
			// ログインユーザが対象者を承認できる場合
			if (isApprovable(humanDto, routeSet)) {
				// 承認すべき申請者追加
				list.add(humanDto);
			}
		}
		return list;
	}
	
	/**
	 * ログインユーザが対象者を承認できるか確認する。<br>
	 * <br>
	 * 対象者のルート適用情報を取得し、
	 * 承認者(ログインユーザ)がユニットとして登録されているルート群に<br>
	 * 含まれるかを確認する。<br>
	 * <br>
	 * @param humanDto 対象者人事情報
	 * @param routeSet 承認者(ログインユーザ)がユニットとして登録されているルート群
	 * @return 確認結果(true：ログインユーザが対象者を承認できる、false：できない)
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected boolean isApprovable(HumanDtoInterface humanDto, Set<String> routeSet) throws MospException {
		// フロー区分(勤怠)を準備
		int workflowType = PlatformConst.WORKFLOW_TYPE_TIME;
		// 個人ID及び対象日から、適用されている設定を取得
		RouteApplicationDtoInterface dto = platformMaster.getRouteApplication(humanDto, targetDate, workflowType);
		// ルート適用情報が取得できない場合
		if (dto == null) {
			// ログインユーザが対象者を承認でないと判断
			return false;
		}
		// ルート群に含まれるかを確認
		return routeSet.contains(dto.getRouteCode());
	}
	
	/**
	 * 検索条件(部下)を設定する。<br>
	 */
	protected void setSubordinateParams() {
		// 検索条件設定(休退職区分)
		setStateType(PlatformConst.EMPLOYEE_STATE_PRESENCE);
		// 検索条件設定(下位所属要否)
		setNeedLowerSection(true);
		// 検索条件設定(兼務要否)
		setNeedConcurrent(true);
		// 検索条件設定(操作区分)
		setOperationType(MospConst.OPERATION_TYPE_REFER);
	}
	
	/**
	 * 期間最終日を取得する。<br>
	 * @param startDate 表示期間開始日
	 * @param endDate 表示期間終了日
	 * @return 期間最終日
	 */
	protected Date getEndTargetDate(Date startDate, Date endDate) {
		// 期間内の場合
		if (DateUtility.isTermContain(getSystemDate(), startDate, endDate)) {
			return getSystemDate();
		}
		// 表示期間開始より前の場合
		if (getSystemDate().compareTo(startDate) < 0) {
			return startDate;
		}
		// 表示期間終了より後の場合
		if (getSystemDate().compareTo(endDate) > 0) {
			return endDate;
		}
		return getSystemDate();
	}
	
	@Override
	public void setDisplayYear(int displayYear) {
		this.displayYear = displayYear;
	}
	
	@Override
	public void setTargetYear(int targetYear) {
		this.targetYear = targetYear;
	}
	
	@Override
	public void setTargetMonth(int targetMonth) {
		this.targetMonth = targetMonth;
	}
	
	@Override
	public void setHumanType(String humanType) {
		this.humanType = humanType;
	}
	
}
