/*
 * 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 General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.kintai.common.part;

import java.util.Date;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.dto.HumanBasisDtoInterface;
import jp.mosp.common.part.PartInfo;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.VariousUtil;
import jp.mosp.kintai.common.dao.MKihonDao;
import jp.mosp.kintai.common.dto.MKihonDto;
import jp.mosp.kintai.human.dao.MEmergencyDao;
import jp.mosp.kintai.human.dao.MKojinDao;

/**
 * 人事に関するPartクラス
 * @author yoshida
 *	@version	0.0.4
 */
public class HumanPart extends KintaiBasePart {
	
	/**
	 * M_KIHON
	 */
	public static final String	BASIS_TABLE		= MKihonDao.TABLE;
	
	/**
	 * M_KOJIN
	 */
	public static final String	PERSONAL_TABLE	= MKojinDao.TABLE;
	

	/**
	 * コンストラクタ
	 */
	public HumanPart() {
		super();
	}
	
	/**
	 * コンストラクタ
	 * @param partInfo Partを利用する際に必要な情報
	 */
	public HumanPart(PartInfo partInfo) {
		super(partInfo);
	}
	

	/**
	 * MKihonDaoインスタンス
	 */
	private MKihonDao	kihonDao;
	

	/**
	 * M_KIHONテーブル用のDAO取得
	 * @return	初期化済みMKihonDaoインスタンス
	 * @throws Exception	例外処理が発生した場合
	 */
	public MKihonDao getMKihonDao() throws Exception {
		if (VariousUtil.isNull(kihonDao)) {
			kihonDao = (MKihonDao)getPreparedDao(MKihonDao.class.getCanonicalName());
		}
		return kihonDao;
	}
	

	/**
	 * MKojinDaoインスタンス
	 */
	private MKojinDao	kojinDao;
	

	/**
	 * M_KOJINテーブル用のDAOの取得
	 * @return	初期化済みMKojinDaoインスタンス
	 * @throws Exception	例外処理が発生した場合
	 */
	public MKojinDao getMKojinDao() throws Exception {
		if (VariousUtil.isNull(kojinDao)) {
			kojinDao = (MKojinDao)getPreparedDao(MKojinDao.class.getCanonicalName());
		}
		return kojinDao;
	}
	

	/**
	 * MEmergencyDaoインスタンス
	 */
	private MEmergencyDao	emergencyDao;
	

	/**
	 * M_EMERGENCYテーブル用のDAOの取得
	 * @return	初期化済みMEmergencyDaoインスタンス
	 * @throws Exception	例外処理が発生した場合
	 */
	public MEmergencyDao getMEmergencyDao() throws Exception {
		if (VariousUtil.isNull(emergencyDao)) {
			emergencyDao = (MEmergencyDao)getPreparedDao(MEmergencyDao.class.getCanonicalName());
		}
		return emergencyDao;
	}
	
	/**
	 * 人事基本情報取得(M_KIHON)
	 * @param kCode 情報取得対象社員コード
	 * @return 人事基本情報(MKihonDto)
	 * @throws Exception 	例外処理が発生した場合
	 */
	public MKihonDto getBasisInfo(String kCode) throws Exception {
		// 情報の取得
		return getMKihonDao().findForKey(kCode);
	}
	
	/**
	 * 社員氏名取得(M_KIHON)
	 * @param kCode 情報取得対象社員コード
	 * @return 社員氏名
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String getKName(String kCode) throws Exception {
		MKihonDto dto = getBasisInfo(kCode);
		if (VariousUtil.isNull(dto)) {
			return kCode;
		}
		return dto.getSimei();
	}
	
	/**
	 * 社員コード取得(M_KIHON)(現所属)
	 * @param sectionCode 検索所属コード
	 * @return 社員コードリスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[] getBasisArray(String sectionCode) throws Exception {
		return getBasisArray(sectionCode, DateUtil.getSystemDate());
	}
	
	/**
	 * 社員コード取得(M_KIHON)(指定年月日所属)
	 * @param sectionCode 検索所属コード
	 * @param targetMonth 選択年月日
	 * @return 社員コードリスト
	 * @throws Exception	例外処理が発生した場合
	 */
	public String[] getBasisArray(String sectionCode, Date targetMonth) throws Exception {
		// 情報の取得
		List<MKihonDto> listKihon = getMKihonDao().findForSection(sectionCode, DateUtil.convDateToInteger(targetMonth),
				DateUtil.convDateToInteger(part().calculate().getEndDate(targetMonth)));
		// 配列の作成
		String[] aryKihon = new String[listKihon.size()];
		for (int i = 0; i < aryKihon.length; i++) {
			aryKihon[i] = listKihon.get(i).getKCode();
		}
		return aryKihon;
	}
	
	/**
	 * 社員コード取得(M_KIHON)
	 * @return 社員コードリスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[][] getBasisArrayAll() throws Exception {
		// 情報の取得
		List<MKihonDto> listKihon = getMKihonDao().findAll();
		// 配列の作成
		String[][] aryKihon = new String[listKihon.size()][2];
		for (int i = 0; i < aryKihon.length; i++) {
			aryKihon[i][0] = listKihon.get(i).getKCode();
			aryKihon[i][1] = listKihon.get(i).getSimei();
		}
		return aryKihon;
	}
	
	/**
	 * 社員コード取得(M_KIHON)
	 * @return 社員コードリスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[][] getBasisArrayForApproval() throws Exception {
		// 情報の取得
		List<MKihonDto> listKihon = getMKihonDao().findForAuth(CommonConst.AUTHORITY_MANAGER,
				CommonConst.AUTHORITY_SENIORS, DateUtil.convDateToInteger(DateUtil.getSystemDate()));
		// 配列の作成
		String[][] aryKihon = new String[listKihon.size()][2];
		for (int i = 0; i < aryKihon.length; i++) {
			aryKihon[i][0] = listKihon.get(i).getKCode();
			aryKihon[i][1] = listKihon.get(i).getSimei();
		}
		return aryKihon;
	}
	
	/**
	 * 社員コード、所属コード取得(M_KIHON)
	 * @return 社員コードリスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[][] getBasisArrayAllWithSectionCode() throws Exception {
		// 情報の取得
		List<MKihonDto> listKihon = getMKihonDao().findAll();
		// 配列の作成
		String[][] aryKihon = new String[listKihon.size()][2];
		for (int i = 0; i < aryKihon.length; i++) {
			aryKihon[i][0] = listKihon.get(i).getKCode();
			aryKihon[i][1] = listKihon.get(i).getSCode();
		}
		return aryKihon;
	}
	
	/**
	 * 社員コード、所属コード取得(M_KIHON)
	 * @since	0.0.2
	 * @return 社員コードリスト
	 * @throws Exception 	例外処理が発生した場合
	 */
	public String[][] getBasisArrayAllWithOfficeCode() throws Exception {
		// 情報の取得
		List<MKihonDto> listKihon = getMKihonDao().findAll();
		// 配列の作成
		String[][] aryKihon = new String[listKihon.size()][2];
		for (int i = 0; i < aryKihon.length; i++) {
			aryKihon[i][0] = listKihon.get(i).getKCode();
			aryKihon[i][1] = listKihon.get(i).getJCode();
		}
		return aryKihon;
	}
	
	/**
	 * 選択社員所属社員コード一覧取得(M_KIHON)
	 * @param kCode		対象社員コード
	 * @return	社員コードリスト
	 * @throws Exception	例外処理が発生した場合
	 */
	public String[][] getBasisArrayForBelongSection(String kCode) throws Exception {
		MKihonDto dto = getBasisInfo(kCode);
		// 検索
		List<MKihonDto> listMKihon = getMKihonDao().findForCondition(dto.getSCode(), dto.getJCode(), kCode,
				part().mospuser().getUserInfoForKCode(kCode).getDataLevel(),
				DateUtil.convDateToInteger(DateUtil.getSystemDate()));
		String[][] aryBasis = new String[listMKihon.size()][2];
		for (int i = 0; i < aryBasis.length; i++) {
			aryBasis[i][0] = listMKihon.get(i).getKCode();
			aryBasis[i][1] = listMKihon.get(i).getSimei();
		}
		return aryBasis;
	}
	
	/**
	 * 勤続年数（月数）取得
	 * @param kCode 社員コード
	 * @return y.m<br>月はそのまま
	 * 				[例] 26月→2.02年
	 * @throws Exception 	例外処理が発生した場合
	 */
	public double getYearsOfService(String kCode) throws Exception {
		MKihonDto dto = getBasisInfo(kCode);
		int difference = 0;
		if (VariousUtil.isNotNull(dto)) {
			difference = DateUtil.getMonthRemainder(DateUtil.getSystemDate(), DateUtil.convIntegerDateToDate(dto
				.getNyDate()));
		}
		return difference / 12 + difference % 12 / 100;
	}
	
	/**
	 * 退職判断
	 * @param kCode		対象社員コード
	 * @return
	 * <p>
	 * 退職の場合。true、そうでない場合false。
	 * </p>
	 * @throws Exception	例外処理が発生した場合
	 */
	public boolean isRetiredEmployee(String kCode) throws Exception {
		return isRetiredEmployee(getBasisInfo(kCode));
	}
	
	/**
	 * 退職判断
	 * @since	0.0.3
	 * @param dto	対象社員人事情報
	 * @return
	 * <p>
	 * 退職の場合。true、そうでない場合false。
	 * </p>
	 */
	public static boolean isRetiredEmployee(MKihonDto dto) {
		if (VariousUtil.chkExistDto(dto)) {
			// 退職区分が退職且つ、退職日付が本日より前の場合。
			if (String.valueOf(CommonConst.RETIREMENT_FLAG_ON).equals(dto.getKnKubun())
					&& (dto.getTsDate() > 0 && dto.getTsDate() < DateUtil.convDateToInteger(DateUtil.getSystemDate()))) {
				return true;
			}
			return false;
		}
		return true;
	}
	
	/**
	 * 在職社員情報取得
	 * @param kCode		対象社員コード
	 * @return			在職社員情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public MKihonDto getAvailableUserInfo(String kCode) throws Exception {
		MKihonDto dto = getBasisInfo(kCode);
		if (VariousUtil.chkExistDto(dto)) {
			// 退職区分が退職の場合。
			if (isRetiredEmployee(dto)) {
				return null;
			}
			// 退職区分が休職の場合。
			if (String.valueOf(CommonConst.RETIREMENT_FLAG_LEAVE).equals(dto.getKnKubun())) {
				return null;
			}
		}
		return dto;
	}
	
	/**
	 * ログイン社員基本情報取得
	 * @return	ログイン社員基本情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public MKihonDto getBasisInfoOfUser() throws Exception {
		return getBasisInfo(user.getKCode());
	}
	
	/**
	 * 対象社員入社年月日取得
	 * @since 0.0.4
	 * @param dto 対象社員人事基本情報
	 * @return 入社年月日
	 */
	public static Date getEmployDate(HumanBasisDtoInterface dto) {
		return DateUtil.convIntegerDateToDate(dto.getNyDate());
	}
	
	/**
	 * 対象社員入社年月日取得
	 * @since 0.0.4
	 * @param kCode 対象社員コード
	 * @return 入社年月日 
	 * @throws Exception 	例外処理が発生した場合
	 */
	public Date getEmployDate(String kCode) throws Exception {
		return getEmployDate(getBasisInfo(kCode));
	}
	
	/**
	 * 社員存在確認
	 * @param kCode 対象社員コード
	 * @return 対象社員が存在する場合true、そうでない場合false
	 * @throws Exception 	例外処理が発生した場合
	 */
	public boolean isExist(String kCode) throws Exception {
		return VariousUtil.isNotNull(getBasisInfo(kCode));
	}
	
	/**
	 * 社員コード重複確認
	 * @param kCode 対象社員コード
	 * @return 対象社員コードの重複が無い場合true、そうでない場合false
	 * @throws Exception 	例外処理が発生した場合
	 */
	public boolean isNotUseKCode(String kCode) throws Exception {
		return VariousUtil.isNull(getBasisInfo(kCode));
	}
	
}
