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

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

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.part.MosPCodePart;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.NumberUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.VariousUtil;
import jp.mosp.kintai.common.action.AttendanceTotalAction;
import jp.mosp.kintai.common.part.LaborAgreementPart;
import jp.mosp.kintai.common.part.PaidHolidayPart;
import jp.mosp.kintai.payroll.dto.KdPaidHolidayDto;
import jp.mosp.kintai.payroll.dto.ViewPaidHolidayDto;
import jp.mosp.kintai.payroll.vo.PaidHolidayCardVo;

/**
 * @author yoshida
 *
 */
public class PaidHolidayCardAction extends AttendanceTotalAction {
	
	// コマンド
	/**
	 * P1116
	 */
	public static final String	CMD_CARD_SELECT	= "P1116";
	private static final String	CMD_CARD_UPDATE	= "P1117";
	

	/**
	 * コンストラクタ
	 */
	public PaidHolidayCardAction() {
		super();
	}
	
	public void action() throws Exception {
		// VOの取得
		prepareVo(false);
		// 初期処理
		init();
		// コマンド毎の処理
		if (CMD_CARD_SELECT.equals(cmd)) {
			select();
		} else if (CMD_CARD_UPDATE.equals(cmd)) {
			update();
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}
	
	@Override
	protected BaseVo getSpecificVo() {
		return new PaidHolidayCardVo();
	}
	
	@Override
	protected void init() throws Exception {
		confirmPayrollAuth();
	}
	
	@Override
	protected void select() throws Exception {
		PaidHolidayCardVo vo = (PaidHolidayCardVo)getVo();
		vo.setHidSelectKCode(key1);
		vo.setHidSelectYearMonth(key2);
		// 有休情報の設定
		setPaidHolidayInfo();
	}
	
	@Override
	protected void update() throws Exception {
		PaidHolidayCardVo vo = (PaidHolidayCardVo)getVo();
		vo.setParams(request);
		vo.validate();
		String kCode = vo.getHidSelectKCode();
		Date yearMonth = DateUtil.getYearMonth(vo.getHidSelectYear(), vo.getHidSelectMonth());
		KdPaidHolidayDto monthlyDto = part().paidHoliday().getPaidHolidayInfo(kCode, getStartDate(yearMonth),
				CommonConst.CODE_PROCESS_MONTHLY);
		if (VariousUtil.isNotNull(monthlyDto)) {
			boolean commitFlag = true;
			// 付与処理
			double supplyLastDay = NumberUtil.getDoubleParam(vo.getTxtSupplyLastDays());
			double supplyDay = NumberUtil.getDoubleParam(vo.getTxtSupplyDays());
			int supplyLastHour = 0;
			int supplyHour = 0;
			if (part().mospcode().useHourPaidHolidayFunction()) {
				supplyLastHour = NumberUtil.getIntParam(vo.getTxtSupplyLastHour());
				supplyHour = NumberUtil.getIntParam(vo.getTxtSupplyHour());
			}
			if (supplyLastDay > 0 || supplyDay > 0 || supplyLastHour > 0 || supplyHour > 0) {
				// 付与情報
				KdPaidHolidayDto supplyDto = PaidHolidayPart.createSupplyDto(kCode, yearMonth, supplyLastDay,
						supplyLastHour, supplyDay, supplyHour);
				// 有休情報の登録
				registPaidHoliday(supplyDto, false);
			}
			// 廃棄処理
			double wasteLastDay = NumberUtil.getDoubleParam(vo.getTxtWasteLastDays());
			double wasteDay = NumberUtil.getDoubleParam(vo.getTxtWasteDays());
			int wasteLastHour = 0;
			int wasteHour = 0;
			// 時間単位年休
			if (part().mospcode().useHourPaidHolidayFunction()) {
				wasteLastHour = NumberUtil.getIntParam(vo.getTxtWasteLastHour());
				wasteHour = NumberUtil.getIntParam(vo.getTxtWasteHour());
			}
			if (wasteLastDay > 0 || wasteDay > 0 || wasteLastHour > 0 || wasteHour > 0) {
				// 残日数のチェック
				if (monthlyDto.getLastRemainDays() - wasteLastDay >= 0 && monthlyDto.getRemainDays() - wasteDay >= 0) {
					// 残時間のチェック
					if (monthlyDto.getLastRemainHour() - wasteLastHour < 0
							|| monthlyDto.getRemainHour() - wasteHour < 0) {
						// エラーメッセージ
						addErrMessage(getMessage("WC2052", ""));
						commitFlag = false;
					} else {
						// 廃棄情報
						KdPaidHolidayDto wasteDto = PaidHolidayPart.createWasteDto(kCode, yearMonth, wasteLastDay,
								wasteLastHour, wasteDay, wasteHour);
						// 有休情報の登録
						registPaidHoliday(wasteDto, false);
					}
				} else {
					// エラーメッセージ
					addErrMessage(getMessage("WC2052", ""));
					commitFlag = false;
				}
			}
			// 時間単位取得可能数
			if (part().mospcode().useHourPaidHolidayFunction()) {
				// 労使協定情報
				setLaborAgreementInfo(kCode, getStartDate(yearMonth));
				int maxPossible = PaidHolidayPart.getPrescribedHour(LaborAgreementPart.getPrescribedTime(agreement))
						* PaidHolidayPart.MAX_POSSIBLE_DAYS;
				int supplyPossible = NumberUtil.getIntParam(vo.getTxtSupplyPossible());
				int wastePossible = NumberUtil.getIntParam(vo.getTxtWastePossible());
				if (supplyPossible > 0 || wastePossible > 0) {
					int possible = monthlyDto.getPossible() + supplyPossible - wastePossible;
					// 時間単位取得可能数のチェック
					if (possible >= 0 && maxPossible >= possible) {
						// 時間単位取得可能数のセット
						monthlyDto.setPossible(possible);
						// 有休情報の登録
						registPaidHoliday(monthlyDto, true);
					} else {
						// エラーメッセージ
						addErrMessage(getMessage("WC2027", vo.NAM_POSSIBLE + MospConst.DATA_SEPARATOR + 0
								+ MospConst.DATA_SEPARATOR + maxPossible));
						commitFlag = false;
					}
				}
			}
			if (commitFlag) {
				// コミット
				commit();
				// メッセージ
				setMessage(getMessage(MospConst.MSG_UPDATE, ""));
			}
		} else {
			// エラーメッセージ
			addErrMessage(getMessage("WC2053", StringUtil.combineByComma(getKName(kCode), DateUtil
				.convDateToJPYearMonthShort(yearMonth))));
		}
		// 有休情報の設定
		setPaidHolidayInfo();
	}
	
	/**
	 * 有休情報の設定
	 * @throws Exception   例外処理が発生した場合
	 */
	private void setPaidHolidayInfo() throws Exception {
		PaidHolidayCardVo vo = (PaidHolidayCardVo)getVo();
		vo.setDefaultValue();
		String kCode = vo.getHidSelectKCode();
		setLabelBasisInfo(kCode);
		// 選択年月
		String[] selectYearMonth = StringUtil.divideByHyphen(vo.getHidSelectYearMonth());
		vo.setHidSelectYear(selectYearMonth[0]);
		vo.setHidSelectMonth(selectYearMonth[1]);
		Date targetMonth = DateUtil.getYearMonth(vo.getHidSelectYear(), vo.getHidSelectMonth());
		vo.setLblSelectYearMonth(DateUtil.convDateToJPYearMonthShort(targetMonth));
		// 勤怠集計月の有休情報
		Map<String, Double> map = part().paidHoliday().getPaidHolidayInfoMap(kCode, targetMonth);
		KdPaidHolidayDto dto = new KdPaidHolidayDto();
		PaidHolidayPart.setMapInfoToNewInfo(dto, map);
		vo.setHidLastRemainDays(String.valueOf(dto.getLastRemainDays()));
		vo.setHidLastRemainHour(String.valueOf(dto.getLastRemainHour()));
		vo.setHidRemainDays(String.valueOf(dto.getRemainDays()));
		vo.setHidRemainHour(String.valueOf(dto.getRemainHour()));
		vo.setHidPossible(String.valueOf(dto.getPossible()));
		vo.setLblTotalRemainDays(String.valueOf(dto.getLastRemainDays() + dto.getRemainDays()));
		vo.setLblTotalRemainHour(String.valueOf(dto.getLastRemainHour() + dto.getRemainHour()));
		vo.setLblLastRemainDays(vo.getHidLastRemainDays());
		vo.setLblLastRemainHour(vo.getHidLastRemainHour());
		vo.setLblRemainDays(vo.getHidRemainDays());
		vo.setLblRemainHour(vo.getHidRemainHour());
		vo.setLblPossible(vo.getHidPossible());
		// 勤怠集計月を含む過去一年の情報の表示
		Date periodEnd = targetMonth;
		Date periodStart = DateUtil.addYear(periodEnd, -1);
		List<Date> periodList = new ArrayList<Date>();
		Calendar cal = Calendar.getInstance();
		cal.setTime(periodStart);
		while (periodEnd.compareTo(cal.getTime()) > 0) {
			periodList.add(cal.getTime());
			cal.setTime(DateUtil.addMonth(cal.getTime(), 1));
		}
		List<ViewPaidHolidayDto> list = new ArrayList<ViewPaidHolidayDto>();
		for (Date period : periodList) {
			map = part().paidHoliday().getPaidHolidayInfoMap(kCode, period);
			if (VariousUtil.isNotNull(map)) {
				ViewPaidHolidayDto viewDto = new ViewPaidHolidayDto();
				viewDto.setProcessDate(period);
				viewDto.setSupplyDays(PaidHolidayPart.getMapSupplyDays(map));
				viewDto.setSupplyHour(PaidHolidayPart.getMapSupplyHour(map));
				viewDto.setWasteDays(PaidHolidayPart.getMapWasteDays(map));
				viewDto.setWasteHour(PaidHolidayPart.getMapWasteHour(map));
				viewDto.setUseDays(PaidHolidayPart.getMapUseDays(map));
				viewDto.setUseHour(PaidHolidayPart.getMapUseHour(map));
				viewDto.setLastRemainDays(PaidHolidayPart.getMapLastRemainDays(map));
				viewDto.setLastRemainHour(PaidHolidayPart.getMapLastRemainHour(map));
				viewDto.setRemainDays(PaidHolidayPart.getMapRemainDays(map));
				viewDto.setRemainHour(PaidHolidayPart.getMapRemainHour(map));
				list.add(viewDto);
			}
		}
		String[][] aryPaidHoliday = StringUtil.getBlankArray(list.size(), 11);
		int i = 0;
		for (ViewPaidHolidayDto viewDto : list) {
			aryPaidHoliday[i][0] = DateUtil.convDateToJPYearMonthShort(viewDto.getProcessDate());
			aryPaidHoliday[i][1] = String.valueOf(viewDto.getLastRemainDays());
			aryPaidHoliday[i][2] = String.valueOf(viewDto.getLastRemainHour());
			aryPaidHoliday[i][3] = String.valueOf(viewDto.getRemainDays());
			aryPaidHoliday[i][4] = String.valueOf(viewDto.getRemainHour());
			aryPaidHoliday[i][5] = String.valueOf(viewDto.getSupplyDays());
			aryPaidHoliday[i][6] = String.valueOf(viewDto.getSupplyHour());
			aryPaidHoliday[i][7] = String.valueOf(viewDto.getWasteDays());
			aryPaidHoliday[i][8] = String.valueOf(viewDto.getWasteHour());
			aryPaidHoliday[i][9] = String.valueOf(viewDto.getUseDays());
			aryPaidHoliday[i][10] = String.valueOf(viewDto.getUseHour());
			i++;
		}
		vo.setAryPaidHoliday(aryPaidHoliday);
		vo.setUsePaidHolidayHour(false);
		if (part().mospcode().useHourPaidHolidayFunction() && MosPCodePart.afterLegalReformDate(targetMonth)) {
			vo.setUsePaidHolidayHour(true);
		}
	}
	
}
