/*
 * MosP - Mind Open Source Project         http://www.mosp.jp/
 * Copyright (C) 1987-2008 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.payroll.action;

import java.util.Date;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;


import jp.mosp.kintai.action.AttendanceTotalAction;
import jp.mosp.payroll.dao.MKintaiDao;
import jp.mosp.payroll.dao.MKintaiKeisanDao;
import jp.mosp.payroll.dto.MKintaiDto;
import jp.mosp.payroll.vo.CompileAmendmentCardVo;

public class CompileAmendmentCardAction extends AttendanceTotalAction {

	// コマンド
	private static final String CMD_AMENDMENT_CARD_SELECT 	= "P1046";	// 表示(選択)
	private static final String CMD_AMENDMENT_CARD_REGIST 	= "P1047";	// 登録

	/**
	 * コンストラクタ
	 */
	public CompileAmendmentCardAction() {
		super();
	}

	/**
	 * アクション
	 */
	public void action() throws Exception {
		// DBコネクション取得
		getConnection();
		// PAYROLL権限確認
		confirmPayrollAuth();
		// VOの取得及び設定
		CompileAmendmentCardVo vo = new CompileAmendmentCardVo();
		vo.initVo(cfg, msg, cmd, aspUser, user);
		vo.setParams(request);
		// VO及びフォワード先URLの設定
		setVo(vo);
		setUrl(vo.getRetUrl());
		// DTOの取得
		MKintaiDto dto;
		Object obj = session.getAttribute(MospConst.ATT_DTO);
		dto = obj instanceof MKintaiDto ? (MKintaiDto)obj : null;
		// プルダウンリストの設定
		setPullDownList(vo);
		// コマンド毎の処理
		if (cmd.equals(CMD_AMENDMENT_CARD_SELECT)) {
			// 表示(キーで情報を検索)
			// データの取得
			dto = select(vo);
			// セッションにDTOをセット
			session.setAttribute(MospConst.ATT_DTO, dto);
		} else if (cmd.equals(CMD_AMENDMENT_CARD_REGIST)) {
			// 登録
			dto = regist(vo, dto);
			// コミット
			commit();
			// モード設定
			vo.setMode(CompileAmendmentCardVo.MODE_EDIT);
			// セッションにDTOをセット
			session.setAttribute(MospConst.ATT_DTO, dto);
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}

	/**
	 * 選択
	 * @param vo
	 * @throws Exception
	 */
	private MKintaiDto select(CompileAmendmentCardVo vo) throws Exception {
		// DBコネクションの取得
		if (conn == null) {
			getConnection();
		}
		// 社員コード取得
		String kcode = getBasisInfo(key1).getKCode();
		// DAOの宣言
		MKintaiDao dao = new MKintaiDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		// DTOのセット
		MKintaiDto dto;
		// 勤怠集計検索
		MKintaiDto currentDto = dao.findForKey(kcode, key2);
		// 選択年月
		String[] target = util.divideByHyphen(key2, 1);
		Date targetMonth = util.getFirstDateOfMonth(target[0], target[1]);
		if (chkExistDto(currentDto)) {
			// DTOに現在の値をセット
			dto = currentDto;
		} else {
			// 勤怠データ取得			
			getAttendanceList(kcode, targetMonth);
			// 日集計データ時間設定
			setHours();
			// 勤怠月集計
			dto = setCompileMonth(kcode, targetMonth);
		}
		// VOに情報をセット
		vo.setFields(dto);
		// 勤怠集計情報設定
		setAmendmentInfo(vo, kcode, targetMonth);
		// モードの設定
		// DAOの準備
		MKintaiKeisanDao mKintaiKeisanDao = new MKintaiKeisanDao();
		mKintaiKeisanDao.initDao(cfg, cmd, aspUser, user, conn);
		if (!chkExistDto(mKintaiKeisanDao.findForCalc())) {
			vo.setMode(CompileAmendmentCardVo.MODE_IMPOSSIBLE);
		} else if (targetMonth.compareTo(getCalcMonth()) < 0) {
			vo.setMode(CompileAmendmentCardVo.MODE_IMPOSSIBLE);
		} else {
			vo.setMode(CompileAmendmentCardVo.MODE_EDIT);
		}
		return dto;
	}

	/**
	 * 登録処理
	 * @param vo
	 * @param dto
	 * @throws Exception
	 */
	private MKintaiDto regist(CompileAmendmentCardVo vo, MKintaiDto dto) throws Exception {
		// パラメータの妥当性確認
		vo.validate();
		Date targetMonth = util.getFirstDateOfMonth(vo.getHidYear(), vo.getHidMonth());
		// DAOの準備
		MKintaiDao dao = new MKintaiDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		if (dto == null) {
			dto = new MKintaiDto();
		}
		// DTOの準備
		vo.setDtoFields(dto);
		dto.setSikyuYM(util.convDateToStringYearMonthShort(targetMonth));
		// 存在チェック
		MKintaiDto currentDto = dao.findForKey(vo.getHidKCode(), util.convDateToStringYearMonthShort(targetMonth));
		if (chkExistDto(currentDto)) {
			// 排他確認
			chkExclusive(currentDto, dao.findForUpdate(vo.getHidKCode(), util.convDateToStringYearMonthShort(targetMonth)), vo);
			// データの更新
			dao.update(dto);
		} else {
			// 存在チェック
			chkDuplicate(dao.findForKey(vo.getHidKCode(), util.convDateToStringYearMonthShort(targetMonth)), vo);
			// データの挿入
			dao.insert(dto);
		}
		// DTOの再取得
		MKintaiDto retDto = dao.findForKey(dto.getKCode(), dto.getSikyuYM());
		chkUpdate(retDto);
		// メッセージ設定
		vo.setMessage(MospUtility.getMessage(msg, MospConst.MSG_UPDATE, ""));
		// 勤怠集計情報設定
		setAmendmentInfo(vo, retDto.getKCode(), targetMonth);	
		return retDto;
	}

	/**
	 * プルダウンリスト設定
	 * @param vo
	 * @throws Exception
	 */
	private void setPullDownList(CompileAmendmentCardVo vo) throws Exception {
		// DBコネクションの取得
		if (conn == null) {
			getConnection();
		}
		// 手当名称
		vo.aryAllowance = getMosPCodeArray(CommonConst.TID_ALLOWANCE_NAME);
		// 休暇理由名称
		vo.aryHolidayReason = getMosPCodeArray(CommonConst.TID_LEAVE_REASON);
		// 皆勤手当有無
		vo.aryPerfectAttendanceFlag = util.getExistenceArray();
	}

	/**
	 * 勤怠集計情報設定
	 * @param vo 対象VO
	 * @param kcode 選択社員コード
	 * @param targetMonth 対象年月
	 * @throws Exception
	 */
	private void setAmendmentInfo(CompileAmendmentCardVo vo, String kcode, Date targetMonth) throws Exception {
		// 人事情報設定
		vo.setHidKCode(kcode);
		vo.setLblKCode(kcode);
		vo.setLblKName(getKName(kcode));
		vo.setLblSection(getSectionInfo(getBasisInfo(kcode).getSCode()).getSName());
		// 勤怠集計情報設定
		vo.setHidYear(String.valueOf(MospUtility.getYear(targetMonth)));
		vo.setHidMonth(String.valueOf(MospUtility.getMonth(targetMonth)));
		vo.setLblSelectDate(MospUtility.getDateString(targetMonth, CommonConst.FORMAT_YEAR_MONTH));
	}

}
