/*
 * 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.platform.human.action;

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

import jp.mosp.framework.base.BaseVo;
import jp.mosp.framework.base.MospException;
import jp.mosp.framework.utils.MospUtility;
import jp.mosp.platform.bean.system.PositionReferenceBeanInterface;
import jp.mosp.platform.bean.system.SectionReferenceBeanInterface;
import jp.mosp.platform.constant.PlatformConst;
import jp.mosp.platform.dto.human.ConcurrentDtoInterface;
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.human.SuspensionDtoInterface;
import jp.mosp.platform.dto.system.EmploymentContractDtoInterface;
import jp.mosp.platform.dto.system.PositionDtoInterface;
import jp.mosp.platform.dto.system.SectionDtoInterface;
import jp.mosp.platform.dto.system.WorkPlaceDtoInterface;
import jp.mosp.platform.human.base.PlatformHumanAction;
import jp.mosp.platform.human.constant.PlatformHumanConst;
import jp.mosp.platform.human.vo.HumanInfoVo;

/**
 * 社員一覧画面で選択した社員の人事情報をまとめて表示する。<br>
 * <br>
 * 以下のコマンドを扱う。
 * <ul><li>
 * {@link #CMD_SELECT}
 * </li><li>
 * {@link #CMD_SEARCH}
 * </li><li>
 * {@link #CMD_RE_SEARCH}
 * </li></ul>
 * {@link #CMD_TRANSFER}
 * </li><li>
 */
public class HumanInfoAction extends PlatformHumanAction {
	
	/**
	 * 選択表示コマンド。<br>
	 * <br>
	 * 社員一覧画面で選択された社員の個人ID及び対象日を用いて各種情報を表示する。<br>
	 */
	public static final String	CMD_SELECT		= "PF1121";
	
	/**
	 * 検索コマンド。<br>
	 * <br>
	 * 社員コード入力欄・有効日入力欄に入力された社員コード・有効日を基に検索する。
	 * 条件に当てはまる社員の人事情報一覧を表示する。<br>
	 * 社員コード順にページを送るボタンがクリックされた場合には
	 * 遷移元の社員一覧リスト検索結果を参照して前後それぞれページ移動を行う。<br>
	 * 再表示ボタンがクリックされた場合は現在表示している社員の有効日入力欄に
	 * 入力された有効日の時点での人事情報一覧を表示する。<br>
	 * 入力した社員コードや有効日が存在しない、またはそれぞれ入力されていない状態で
	 * 「検索ボタン」「再表示ボタン」がクリックされた場合はエラーメッセージにて通知。<br>
	 * 現在表示されている社員の社員コードの前後にデータが存在しない時に
	 * コード順送りボタンをクリックした場合も同様にエラーメッセージにて通知。<br>
	 */
	public static final String	CMD_SEARCH		= "PF1122";
	
	/**
	 * 再表示コマンド。<br>
	 * <br>
	 * パンくずリスト等を用いてこれよりも奥の階層の画面から改めて遷移した場合、
	 * 各種情報の登録状況が更新された状態で再表示を行う。<br>
	 * <br>
	 * 人事管理共通情報にある「再表示」ボタンは、当該コマンドでなく
	 * {@link HumanInfoAction#CMD_SELECT}をリクエストする。<br>
	 */
	public static final String	CMD_RE_SEARCH	= "PF1123";
	
	/**
	 * 画面遷移コマンド。<br>
	 * <br>
	 * 必要な情報をMosP処理情報に設定して、連続実行コマンドを設定する。<br>
	 */
	public static final String	CMD_TRANSFER	= "PF1126";
	

	/**
	 * {@link PlatformHumanAction#PlatformHumanAction()}を実行する。<br>
	 * パンくずリスト用コマンドを設定する。
	 */
	public HumanInfoAction() {
		super();
		// パンくずリスト用コマンド設定
		topicPathCommand = CMD_RE_SEARCH;
	}
	
	@Override
	public void action() throws MospException {
		// コマンド毎の処理
		if (mospParams.getCommand().equals(CMD_SELECT)) {
			// 選択
			prepareVo(true, false);
			select();
		} else if (mospParams.getCommand().equals(CMD_SEARCH)) {
			// 検索
			prepareVo(true, false);
			search();
		} else if (mospParams.getCommand().equals(CMD_RE_SEARCH)) {
			// 再表示
			prepareVo(true, false);
			reSearch();
		} else if (mospParams.getCommand().equals(CMD_TRANSFER)) {
			// 画面遷移
			prepareVo(true, false);
			transfer();
		} else {
			throwInvalidCommandException();
		}
	}
	
	@Override
	protected BaseVo getSpecificVo() {
		return new HumanInfoVo();
	}
	
	/**
	 * 選択表示処理を行う。
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void select() throws MospException {
		// 人事管理共通情報利用設定
		setPlatformHumanSettings(CMD_SEARCH, PlatformHumanConst.MODE_HUMAN_SHOW_ALL);
		// 人事管理共通情報設定
		setTargetHumanCommonInfo();
		// 項目初期化
		setDefaultValues();
		// 各種人事情報設定
		setHumanInfo();
	}
	
	/**
	 * 検索処理を行う。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void search() throws MospException {
		// 人事管理共通情報の検索
		searchHumanCommonInfo();
		// 項目初期化
		setDefaultValues();
		// 各種人事情報設定
		setHumanInfo();
	}
	
	/**
	 * 再表示処理を行う。<br>
	 * パンくずリストからVOを取得し、VOに保持されている対象社員コード及び有効日で
	 * 各種人事情報を取得及び設定する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void reSearch() throws MospException {
		// VO取得
		HumanInfoVo vo = (HumanInfoVo)mospParams.getVo();
		// 人事管理共通情報設定
		setHumanCommonInfo(vo.getPersonalId(), vo.getTargetDate());
		// 項目初期化
		setDefaultValues();
		// 各種人事情報設定
		setHumanInfo();
	}
	
	/**
	 * 対象個人ID、対象日等をMosP処理情報に設定し、
	 * 譲渡Actionクラス名に応じて連続実行コマンドを設定する。<br>
	 */
	protected void transfer() {
		// VO取得
		HumanInfoVo vo = (HumanInfoVo)mospParams.getVo();
		// 譲渡Actionクラス名取得
		String actionName = getTransferredAction();
		// MosP処理情報に対象個人IDを設定
		setTargetPersonalId(vo.getPersonalId());
		// MosP処理情報に対象日を設定
		setTargetDate(vo.getTargetDate());
		// 譲渡Actionクラス名毎に処理
		if (actionName.equals(BasicListAction.class.getName())) {
			// 履歴一覧
			mospParams.setNextCommand(BasicListAction.CMD_SELECT);
		} else if (actionName.equals(BasicCardAction.class.getName())) {
			// 履歴追加・履歴編集
			mospParams.setNextCommand(BasicCardAction.CMD_ADD_SELECT);
		} else if (actionName.equals(EntranceCardAction.class.getName())) {
			// 社員入社情報の編集
			mospParams.setNextCommand(EntranceCardAction.CMD_SELECT);
		} else if (actionName.equals(ConcurrentCardAction.class.getName())) {
			// 兼務情報の登録・更新・削除
			mospParams.setNextCommand(ConcurrentCardAction.CMD_SELECT);
		} else if (actionName.equals(SuspensionCardAction.class.getName())) {
			// 休職情報の登録・更新・削除
			mospParams.setNextCommand(SuspensionCardAction.CMD_SELECT);
		} else if (actionName.equals(RetirementCardAction.class.getName())) {
			// 退職情報の登録・更新・削除
			mospParams.setNextCommand(RetirementCardAction.CMD_SELECT);
		}
	}
	
	/**
	 * VOに初期値を設定する。<br>
	 */
	public void setDefaultValues() {
		// VO取得
		HumanInfoVo vo = (HumanInfoVo)mospParams.getVo();
		// 初期値設定
		vo.setLblEntranceDate("");
		vo.setLblEmployment("");
		vo.setLblEmployeeKana("");
		vo.setLblWorkPlace("");
		vo.setLblSection("");
		vo.setLblPosition("");
		vo.setLblRetirementDate("");
		vo.setLblRetirementReason("");
		vo.setLblRetirementDetail("");
		vo.setArySuspensionStartDate(new String[0]);
		vo.setArySuspensionEndDate(new String[0]);
		vo.setArySuspensionsScheduleEndDate(new String[0]);
		vo.setArySuspensionReason(new String[0]);
		vo.setAryConcurrentStartDate(new String[0]);
		vo.setAryConcurrentEndDate(new String[0]);
		vo.setAryConcurrentSectionAbbr(new String[0]);
		vo.setAryConcurrentPositionAbbr(new String[0]);
		vo.setAryConcurrentRemark(new String[0]);
	}
	
	/**
	 * VOに設定されている対象社員コード及び有効日で各種人事情報を取得し、
	 * それらをVOに設定する。<br>
	 * @throws MospException インスタンスの取得及びSQL実行に失敗した場合
	 */
	protected void setHumanInfo() throws MospException {
		// VO取得
		HumanInfoVo vo = (HumanInfoVo)mospParams.getVo();
		// 社員コード及び有効日取得
		String personalId = vo.getPersonalId();
		Date targetDate = vo.getTargetDate();
		// 個人情報取得
		HumanDtoInterface humanDto = reference().human().getHumanInfo(personalId, targetDate);
		// 入社日情報取得
		EntranceDtoInterface entranceDto = reference().entrance().getEntranceInfo(humanDto.getPersonalId());
		// 兼務情報取得
		List<ConcurrentDtoInterface> concurrentDtoList = reference().concurrent().getContinuedConcurrentList(
				humanDto.getPersonalId(), targetDate);
		// 休職情報取得
		List<SuspensionDtoInterface> suspensionDtoList = reference().suspension().getContinuedSuspentionList(
				humanDto.getPersonalId(), targetDate);
		// 退職情報取得
		RetirementDtoInterface retirementDto = reference().retirement().getRetireInfo(humanDto.getPersonalId());
		// VOに情報を設定
		setHumanInfo(humanDto, entranceDto, retirementDto, suspensionDtoList, concurrentDtoList);
	}
	
	/**
	 * 人事情報をVOに設定する。<br>
	 * @param humanDto          人事基本情報
	 * @param entranceDto       入社情報
	 * @param retirementDto     退職情報
	 * @param suspensionDtoList 休職情報
	 * @param concurrentDtoList 兼務情報
	 * @throws MospException インスタンスの取得或いはSQL実行に失敗した場合
	 */
	protected void setHumanInfo(HumanDtoInterface humanDto, EntranceDtoInterface entranceDto,
			RetirementDtoInterface retirementDto, List<SuspensionDtoInterface> suspensionDtoList,
			List<ConcurrentDtoInterface> concurrentDtoList) throws MospException {
		// VO取得
		HumanInfoVo vo = (HumanInfoVo)mospParams.getVo();
		// 所属参照クラス、職位参照クラス取得
		SectionReferenceBeanInterface sectionReference = reference().section();
		PositionReferenceBeanInterface positionReference = reference().position();
		// 人事基本情報設定
		vo.setLblEmployeeKana(MospUtility.getHumansName(humanDto.getFirstKana(), humanDto.getLastKana()));
		// 勤務地情報設定
		WorkPlaceDtoInterface workPlaceDto = reference().workPlace().getWorkPlaceInfo(humanDto.getWorkPlaceCode(),
				humanDto.getActivateDate());
		if (workPlaceDto != null) {
			vo.setLblWorkPlace(workPlaceDto.getWorkPlaceName());
		}
		// 所属情報設定
		SectionDtoInterface sectionDto = sectionReference.getSectionInfo(humanDto.getSectionCode(), humanDto
			.getActivateDate());
		if (sectionDto != null) {
			vo.setLblSection(sectionDto.getSectionName());
		}
		// 職位情報設定
		PositionDtoInterface positionDto = positionReference.getPositionInfo(humanDto.getPositionCode(), humanDto
			.getActivateDate());
		if (positionDto != null) {
			vo.setLblPosition(positionDto.getPositionName());
		}
		// 雇用契約情報設定
		EmploymentContractDtoInterface employmentContractDto = reference().employmentContract().getContractInfo(
				humanDto.getEmploymentContractCode(), humanDto.getActivateDate());
		if (employmentContractDto != null) {
			vo.setLblEmployment(employmentContractDto.getEmploymentContractName());
		}
		// 入社情報設定
		if (entranceDto != null) {
			vo.setLblEntranceDate(getStringDate(entranceDto.getEntranceDate()));
		}
		// 退社情報設定
		if (retirementDto != null) {
			vo.setLblRetirementDate(getStringDate(retirementDto.getRetirementDate()));
			vo.setLblRetirementReason(mospParams.getProperties().getCodeItemName(PlatformConst.CODE_KEY_RETIREMENT,
					retirementDto.getRetirementReason()));
			vo.setLblRetirementDetail(retirementDto.getRetirementDetail());
		}
		// 休職情報作成
		String[] arySuspensionStartDate = new String[suspensionDtoList.size()];
		String[] arySuspensionEndDate = new String[suspensionDtoList.size()];
		String[] arySuspensionsScheduleEndDate = new String[suspensionDtoList.size()];
		String[] arySuspensionReason = new String[suspensionDtoList.size()];
		for (int i = 0; i < suspensionDtoList.size(); i++) {
			SuspensionDtoInterface dto = suspensionDtoList.get(i);
			arySuspensionStartDate[i] = getStringDate(dto.getStartDate());
			arySuspensionEndDate[i] = getStringDate(dto.getEndDate());
			arySuspensionsScheduleEndDate[i] = getStringDate(dto.getScheduleEndDate());
			arySuspensionReason[i] = dto.getSuspensionReason();
		}
		// 休職情報設定
		vo.setArySuspensionStartDate(arySuspensionStartDate);
		vo.setArySuspensionEndDate(arySuspensionEndDate);
		vo.setArySuspensionsScheduleEndDate(arySuspensionsScheduleEndDate);
		vo.setArySuspensionReason(arySuspensionReason);
		// 兼務情報作成
		String[] aryConcurrentStartDate = new String[concurrentDtoList.size()];
		String[] aryConcurrentEndDate = new String[concurrentDtoList.size()];
		String[] aryConcurrentSectionAbbr = new String[concurrentDtoList.size()];
		String[] aryConcurrentPositionAbbr = new String[concurrentDtoList.size()];
		String[] aryConcurrentRemark = new String[concurrentDtoList.size()];
		for (int i = 0; i < concurrentDtoList.size(); i++) {
			ConcurrentDtoInterface dto = concurrentDtoList.get(i);
			aryConcurrentStartDate[i] = getStringDate(dto.getStartDate());
			aryConcurrentEndDate[i] = getStringDate(dto.getEndDate());
			aryConcurrentRemark[i] = dto.getConcurrentRemark();
			// 所属情報取得
			SectionDtoInterface concurrentSectionDto = sectionReference.getSectionInfo(dto.getSectionCode(), dto
				.getStartDate());
			if (concurrentSectionDto != null) {
				aryConcurrentSectionAbbr[i] = concurrentSectionDto.getSectionAbbr();
			}
			// 職位情報取得
			PositionDtoInterface concurrentPositionDto = positionReference.getPositionInfo(dto.getPositionCode(), dto
				.getStartDate());
			if (concurrentPositionDto != null) {
				aryConcurrentPositionAbbr[i] = concurrentPositionDto.getPositionAbbr();
			}
		}
		// 兼務情報設定
		vo.setAryConcurrentStartDate(aryConcurrentStartDate);
		vo.setAryConcurrentEndDate(aryConcurrentEndDate);
		vo.setAryConcurrentSectionAbbr(aryConcurrentSectionAbbr);
		vo.setAryConcurrentPositionAbbr(aryConcurrentPositionAbbr);
		vo.setAryConcurrentRemark(aryConcurrentRemark);
	}
}
