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

import java.util.Date;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.BaseVo;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.VariousUtil;
import jp.mosp.kintai.common.action.MosPWorkflowAction;
import jp.mosp.kintai.common.part.KintaiApprovalPart;
import jp.mosp.kintai.common.part.KintaiCommonPart;
import jp.mosp.kintai.dto.MScheduleDto;
import jp.mosp.kintai.dto.MSyukkinboDto;
import jp.mosp.kintai.vo.AttendanceHolidayCardVo;

/**
 * @author yoshida
 *
 */
public class AttendanceHolidayCardAction extends MosPWorkflowAction {
	
	// コマンド
	/**
	 * 
	 */
	public static final String	CMD_HOLIDAY_CARD_SHOW		= "K1130";
	private static final String	CMD_HOLIDAY_CARD_REGIST		= "K1132";
	private static final String	CMD_HOLIDAY_CARD_DELETE		= "K1133";
	private static final String	CMD_HOLIDAY_CARD_DRAFT		= "K1134";
	private static final String	CMD_HOLIDAY_CARD_REFLECT	= "K1135";
	

	/**
	 * コンストラクタ
	 */
	public AttendanceHolidayCardAction() {
		super();
	}
	
	public void action() throws Exception {
		// VOの取得
		prepareVo();
		// 初期処理
		init();
		// コマンド毎の処理
		if (cmd.equals(CMD_HOLIDAY_CARD_SHOW)) {
			// 表示
			show();
		} else if (cmd.equals(CMD_HOLIDAY_CARD_REGIST)) {
			// 登録
			regist(false);
		} else if (cmd.equals(CMD_HOLIDAY_CARD_DELETE)) {
			// 削除
			delete();
		} else if (CMD_HOLIDAY_CARD_DRAFT.equals(cmd)) {
			// 下書き
			regist(true);
		} else if (CMD_HOLIDAY_CARD_REFLECT.equals(cmd)) {
			// 予定の反映
			reflect();
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}
	
	@Override
	protected BaseVo getSpecificVo() {
		return new AttendanceHolidayCardVo();
	}
	
	@Override
	protected void init() throws Exception {
		AttendanceHolidayCardVo vo = (AttendanceHolidayCardVo)getVo();
		// ユーザー情報取得
		getInfo(user.getUserId());
		// 充当日年プルダウン
		vo.aryPltSubstituteYear = StringUtil.getYearArray(MospUtility.getYear(DateUtil.getSystemDate()), 1, 2);
		// 充当日月プルダウン
		vo.aryPltSubstituteMonth = StringUtil.getMonthArray();
		// 充当日日プルダウン
		vo.aryPltSubstituteDay = StringUtil.getDayArray();
		// 休暇理由プルダウン
		vo.aryPltHolidayReason = part().mospcode().getHolidayReasonArray();
		// 休暇証明書プルダウン
		vo.aryPltHolidayCertificate = getMosPCodeArray(CommonConst.TID_HOLIDAY_CERTIFICATE);
		// 勤怠管理コマンド
		setSubTitleMenu();
	}
	
	@Override
	protected void show() throws Exception {
		AttendanceHolidayCardVo vo = (AttendanceHolidayCardVo)getVo();
		// 表示項目の初期化
		vo.initFields();
		vo.setDraft(true);
		// 表示の準備
		setAttendanceInfo();
		// 勤怠検索
		MSyukkinboDto dto = kintai().getSyukkinboInfo(vo.getHidKCode(), vo.getHidDate(), false);
		if (VariousUtil.isNotNull(dto)) {
			// VOに情報を設定
			vo.setFields(dto);
			if (!KintaiApprovalPart.isDraft(dto)) {
				vo.setDraft(false);
			}
		}
		// 表示モードのセット
		setMode(dto);
	}
	
	/**
	 * 休暇登録
	 * @param isDraft		下書きフラグ
	 * @throws Exception	例外処理が発生した場合
	 */
	private void regist(boolean isDraft) throws Exception {
		AttendanceHolidayCardVo vo = (AttendanceHolidayCardVo)getVo();
		vo.setParams(request);
		// パラメータの妥当性確認
		vo.validate();
		// 社員コード
		String kCode = vo.getHidKCode();
		// 対象年月日
		Date targetDate = DateUtil.convStringDateToDate(vo.getHidDate());
		// 勤怠検索
		MSyukkinboDto dto = kintai().getSyukkinboInfo(kCode, targetDate, true);
		// 勤怠情報設定
		setCalcParam();
		// 日次自動計算フラグ
		if (isDailyAutoCalc) {
			// 全休休暇時間
			vo.setHolidayTimes(allHoliday);
		}
		if (VariousUtil.isNull(dto)) {
			// INSERT
			dto = new MSyukkinboDto();
			// 自動計算
			vo.setDtoFields(dto);
			dto.setSyozoku(getBelongSectionCode(kCode));
			if (isDraft) {
				dto.setSnRiyuu(CommonConst.CODE_DRAFT);
			}
			// 存在チェック
			chkDuplicate(kintai().getSyukkinboInfo(dto.getKCode(), dto.getHizuke(), false));
			// 一日年休の承認がある場合、反映
			margeHolidayRequest(dto);
			// 登録フラグ
			boolean insertFlag = true;
			// 有休の場合、残日数を考慮する。
			if (KintaiCommonPart.isAllHoliday(dto)) {
				if (!part().holidayRequest().isApprovedPaidHolidayRequestAll(dto)) {
					insertFlag = checkRemainPaidHoliday(kCode, targetDate, 1, 0);
				}
			}
			// 時間外代休の場合、残日数を考慮する。
			if (part().mospcode().useSubstituteHolidayFunction() && KintaiCommonPart.isSubstituteAll(dto)) {
				if (!part().holidayRequest().isApprovedSubstituteHolidayRequestAll(dto)) {
					insertFlag = checkRemainSubstitute(kCode, targetDate, 1);
				}
			}
			if (insertFlag) {
				// 登録		
				syukkinboDao().insertHoliday(dto);
				// メッセージ設定
				setMessage(getMessage(MospConst.MSG_INSERT, ""));
			}
		} else {
			// 承認済みの場合はメッセージ表示、登録不可
			if (KintaiApprovalPart.isApproved(dto)) {
				// メッセージ設定
				setMessage(getMessage(CommonConst.MSG_ALREADY_APPROVED, getMessageDate(dto)));
			} else {
				// UPDATE
				// 排他確認
				chkExclusive(dto, kintai().getSyukkinboInfo(dto.getKCode(), dto.getHizuke(), true));
				// 自動計算
				vo.setDtoFields(dto);
				if (isDraft) {
					dto.setSnRiyuu(CommonConst.CODE_DRAFT);
				}
				// 一日年休の承認がある場合、反映
				margeHolidayRequest(dto);
				// 更新フラグ
				boolean updateFlag = true;
				// 有休の場合、残日数を考慮する。
				if (KintaiCommonPart.isAllHoliday(dto)) {
					if (!part().holidayRequest().isApprovedPaidHolidayRequestAll(dto)) {
						updateFlag = checkRemainPaidHoliday(kCode, targetDate, 1, 0);
					}
				}
				// 時間外代休の場合、残日数を考慮する。
				if (part().mospcode().useSubstituteHolidayFunction() && KintaiCommonPart.isSubstituteAll(dto)) {
					if (!part().holidayRequest().isApprovedSubstituteHolidayRequestAll(dto)) {
						updateFlag = checkRemainSubstitute(kCode, targetDate, 1);
					}
				}
				if (updateFlag) {
					// 更新
					syukkinboDao().update(dto);
					// メッセージ設定
					setMessage(getMessage(MospConst.MSG_UPDATE, ""));
				}
			}
		}
		// コミット
		commit();
		// 勤怠一覧へ遷移
		setNextCmd(AttendanceListAction.CMD_ATTENDANCE_LIST_RE_SEARCH);
	}
	
	/**
	 * 予定の反映
	 * @throws Exception	例外処理が発生した場合
	 */
	private void reflect() throws Exception {
		AttendanceHolidayCardVo vo = (AttendanceHolidayCardVo)getVo();
		vo.setParams(request);
		// パラメータの妥当性確認
		vo.validate();
		String kCode = vo.getHidKCode();
		String strTargetDate = vo.getHidDate();
		MScheduleDto dto = part().kintai().getScheduleInfo(kCode, strTargetDate);
		if (VariousUtil.isNull(dto)) {
			dto = kintai().createScheduleInfo(part().human().getBasisInfo(kCode),
					DateUtil.convStringDateToDate(strTargetDate), CommonConst.ATTENDANCE_TYPE_HOLIDAY);
			dto.setKKRiyuu(vo.getPltHolidayReason());
		}
		// 休暇申請とマージ
		margeHolidayRequest(dto);
		// VOに情報を設定
		vo.setFields(KintaiCommonPart.copyToSyukkinbo(dto));
	}
	
}
