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

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.dto.CmAspUserDto;
import jp.mosp.common.dto.CmUserDto;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.mospcommon.system.dao.CmAgreementOverTimeDao;
import jp.mosp.mospcommon.system.dao.CmAgreementWorkOnDao;
import jp.mosp.mospcommon.system.dao.CmLaborAgreementDao;
import jp.mosp.mospcommon.system.dao.CmLimitStandardDao;
import jp.mosp.mospcommon.system.dto.CmAgreementOverTimeDto;
import jp.mosp.mospcommon.system.dto.CmAgreementWorkOnDto;
import jp.mosp.mospcommon.system.dto.CmLaborAgreementDto;
import jp.mosp.mospcommon.system.dto.CmLimitStandardDto;

/**
 * 労使協定管理クラス
 * @author yoshida
 *
 */
public class LaborAgreementManager {
	
	/**
	 * 給与グループコード(SALARY_GRP_CD)
	 */
	public static final String		SALARY_GRP_CD	= "SALARY_GRP_CD";
	/**
	 * 社員コード(K_CODE)
	 */
	public static final String		K_CODE			= "K_CODE";
	
	/**
	 * MosPアプリケーション設定(/WEB-INF/mosp.properties)。
	 */
	private Properties				cfg;
	
	/**
	 * リクエストされたCommand。
	 */
	private String					cmd;
	
	/**
	 * ログインASPユーザー。
	 */
	private CmAspUserDto			aspUser;
	
	/**
	 * ログインユーザー。
	 */
	private CmUserDto				user;
	
	/**
	 * DBコネクション。
	 */
	private Connection				conn;
	
	private CmAgreementOverTimeDao	overTimeDao;
	private CmAgreementWorkOnDao	workOnDao;
	private CmLaborAgreementDao		agreementDao;
	private CmLimitStandardDao		standardDao;
	

	/**
	 * コンストラクタ。
	 * @param cfg 		MosPアプリケーション設定。
	 * @param cmd 		リクエストされたCommand。
	 * @param aspUser 	ログインASPユーザー。
	 * @param user 		ログインユーザー。
	 * @param conn 		DBコネクション。
	 */
	public LaborAgreementManager(Properties cfg, String cmd, CmAspUserDto aspUser, CmUserDto user, Connection conn) {
		super();
		this.cfg = cfg;
		this.cmd = cmd;
		this.aspUser = aspUser;
		this.user = user;
		this.conn = conn;
	}
	
	/**
	 * 労使協定情報取得。
	 * @param targetCode 	対象コード
	 * @param targetDate 	対象年月日
	 * @return 労使協定情報
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public AgreementBaseInfo getAgreementInfo(String targetCode, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		// cfgに入っている人事給与連係情報を取得する。
		if (StringUtil.isNotNull(cfg.getProperty(""))) {
			return getGroupAgreementInfo(targetCode, targetDate);
		} else {
			return getKCodeAgreementInfo(targetCode, targetDate);
		}
	}
	
	/**
	 * 社員コードによる労使協定情報取得。
	 * @param kCode			社員コード
	 * @param targetDate	対象年月日
	 * @return	労使協定情報
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public AgreementBaseInfo getKCodeAgreementInfo(String kCode, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		return getAgreementInfo(getKCodeAgreementInfo(kCode), targetDate);
	}
	
	/**
	 * 給与グループコードによる労使協定情報取得。
	 * @param salarygrpcd			給与グループコード
	 * @param targetDate	対象年月日
	 * @return	労使協定情報
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public AgreementBaseInfo getGroupAgreementInfo(String salarygrpcd, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		return getAgreementInfo(getGroupAgreementInfo(salarygrpcd), targetDate);
	}
	
	/**
	 * 社員コードによる労使協定マスタ取得。
	 * @param kCode 社員コード
	 * @return 労使協定マスタ
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public CmLaborAgreementDto getKCodeAgreementInfo(String kCode) throws SQLException, IllegalAccessException,
			NoSuchFieldException {
		return getAgreementDao().findForAgreeType(kCode, K_CODE);
	}
	
	/**
	 * 給与グループコードによる労使協定マスタ取得。
	 * @param salarygrpcd 給与グループコード
	 * @return 労使協定マスタ
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public CmLaborAgreementDto getGroupAgreementInfo(String salarygrpcd) throws SQLException, IllegalAccessException,
			NoSuchFieldException {
		return getAgreementDao().findForAgreeType(salarygrpcd, SALARY_GRP_CD);
	}
	
	/**
	 * 時間外協定コードによる時間外協定マスタ取得。
	 * @param overTimeCode 時間外協定コード
	 * @param targetDate  対象年月日
	 * @return 時間外協定マスタ
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public CmAgreementOverTimeDto getOverTimeAgreementInfo(String overTimeCode, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		return getOverTimeDao().findForAgreement(overTimeCode, targetDate);
	}
	
	/**
	 * 休出協定コードによる休出協定マスタ取得。
	 * @param workOnCode 休出協定コード
	 * @param targetDate  対象年月日
	 * @return 休出協定マスタ
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public CmAgreementWorkOnDto getWorkOnAgreementInfo(String workOnCode, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		return getWorkOnDao().findForAgreement(workOnCode, targetDate);
	}
	
	/**
	 * 限度基準コードによる限度基準マスタ取得。
	 * @param limitCode 限度基準コード
	 * @return 限度基準マスタ
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	public CmLimitStandardDto getLimitStandardInfo(String limitCode) throws SQLException, IllegalAccessException,
			NoSuchFieldException {
		return getStandardDao().findForLimitCode(limitCode);
	}
	
	/**
	 * マスタの情報を労使協定情報にセット。
	 * @param dto 労使協定マスタ
	 * @param targetDate 対象年月日
	 * @return 労使協定情報
	 * @throws SQLException 	SQL例外が発生した場合
	 * @throws IllegalAccessException 	メソッドにアクセスできない場合
	 * @throws NoSuchFieldException 	フィールドが見つからなかった場合
	 */
	private AgreementBaseInfo getAgreementInfo(CmLaborAgreementDto dto, Date targetDate) throws SQLException,
			IllegalAccessException, NoSuchFieldException {
		AgreementInfo info = null;
		if (dto != null) {
			info = new AgreementInfo();
			// 労使協定マスタ情報設定
			setAgreementInfo(info, dto);
			// 時間外協定マスタ取得
			CmAgreementOverTimeDto overTimeDto = getOverTimeAgreementInfo(dto.getOverTimeCode(), targetDate);
			// 限度基準マスタ取得
			setOverTimeInfo(info, overTimeDto);
			setStandardInfo(info, getLimitStandardInfo(info.getLimitCode()));
			// 休出協定マスタ取得
			setWorkOnInfo(info, getWorkOnAgreementInfo(dto.getWorkOnCode(), targetDate));
		}
		return info;
	}
	
	/**
	 * 労使協定マスタ情報設定
	 * @param info 労使協定情報
	 * @param dto 労使協定マスタ
	 */
	private void setAgreementInfo(AgreementInfo info, CmLaborAgreementDto dto) {
		if (dto != null) {
			info.setAgreementDto(dto);
			info.setAgreeCode(dto.getAgreeCode());
			if (SALARY_GRP_CD.equals(dto.getAgreeType())) {
				info.setSalaryGrpCd(dto.getAgreeCode());
			} else {
				info.setKCode(dto.getAgreeCode());
			}
			info.setOverTimeCode(dto.getOverTimeCode());
			info.setWorkOnCode(dto.getWorkOnCode());
		}
	}
	
	/**
	 * 時間外協定マスタ情報設定
	 * @param info 労使協定情報
	 * @param dto 時間外協定マスタ
	 */
	private void setOverTimeInfo(AgreementInfo info, CmAgreementOverTimeDto dto) {
		if (dto != null) {
			info.setOverTimeDto(dto);
			info.setOverWorkTypeName(dto.getWorkTypeName());
			info.setOverCause(dto.getCause());
			info.setOverAgreeType(dto.getAgreeType());
			info.setLimitCode(dto.getLimitCode());
			info.setOverTimeRate(dto.getOverTimeRate());
			info.setCautionMonth(dto.getCautionMonth());
			info.setMonthlyOverTimeRate(dto.getMonthlyOverTimeRate());
			info.setSubAcquireRate(dto.getSubAcquireRate());
			info.setSubAcquireHolidayRate(dto.getSubAcquireHolidayRate());
			info.setSubQuitRate(dto.getSubQuitRate());
			info.setOverStartDate(dto.getStartDate());
		}
	}
	
	/**
	 * 休出協定マスタ情報設定
	 * @param info 労使協定情報
	 * @param dto 休出協定マスタ
	 */
	private void setWorkOnInfo(AgreementInfo info, CmAgreementWorkOnDto dto) {
		if (dto != null) {
			info.setWorkOnDto(dto);
			info.setWorkOnWorkTypeName(dto.getWorkTypeName());
			info.setWorkOnCause(dto.getCause());
			info.setStandardWeekHoliday(dto.getStandardWeekHoliday());
			info.setOfficialHoliday(dto.getOfficialHoliday());
			info.setJapaneseHolidayFlag(dto.getJapaneseHolidayFlag());
			info.setHolidayMasterFlag(dto.getHolidayMasterFlag());
			info.setStandardHolidayRate(dto.getStandardHolidayRate());
			info.setOfficialHolidayRate(dto.getOfficialHolidayRate());
			info.setNumberOfWorkOn(dto.getNumberOfWorkOn());
			info.setWorkOnStartTime(dto.getStartTime());
			info.setWorkOnEndTime(dto.getEndTime());
			info.setWorkOnStartDate(dto.getStartDate());
		}
	}
	
	/**
	 * 限度基準マスタ情報設定
	 * @param info 労使協定情報
	 * @param dto 限度基準マスタ
	 */
	private void setStandardInfo(AgreementInfo info, CmLimitStandardDto dto) {
		if (dto != null) {
			info.setStandardDto(dto);
			info.setLimitName(dto.getLimitName());
			info.setTermType(dto.getTermType());
			info.setPrescribedTime(dto.getPrescribedTime());
			info.setCautionDay(dto.getCautionDay());
			info.setCautionTerm(dto.getCautionTerm());
			info.setCautionYear(dto.getCautionYear());
			info.setLimitDay(dto.getLimitDay());
			info.setLimitTerm(dto.getLimitTerm());
			info.setLimitYear(dto.getLimitYear());
			info.setRateTerm(dto.getRateTerm());
			info.setRateYear(dto.getRateYear());
		}
	}
	
	/**
	 * 労使協定マスタのDAO取得。
	 * @return CmLaborAgreementDaoインスタンス。
	 */
	public CmLaborAgreementDao getAgreementDao() {
		if (agreementDao == null) {
			agreementDao = new CmLaborAgreementDao();
			agreementDao.initDao(cfg, cmd, aspUser, user, conn);
		}
		return agreementDao;
	}
	
	/**
	 * 時間外協定マスタのDAO取得。
	 * @return CmAgreementOverTimeDaoインスタンス。
	 */
	public CmAgreementOverTimeDao getOverTimeDao() {
		if (overTimeDao == null) {
			overTimeDao = new CmAgreementOverTimeDao();
			overTimeDao.initDao(cfg, cmd, aspUser, user, conn);
		}
		return overTimeDao;
	}
	
	/**
	 * 休出協定マスタのDAO取得。
	 * @return CmAgreementWorkOnDaoインスタンス。
	 */
	public CmAgreementWorkOnDao getWorkOnDao() {
		if (workOnDao == null) {
			workOnDao = new CmAgreementWorkOnDao();
			workOnDao.initDao(cfg, cmd, aspUser, user, conn);
		}
		return workOnDao;
	}
	
	/**
	 * 限度基準マスタのDAO取得。
	 * @return CmLimitStandardDaoインスタンス。
	 */
	public CmLimitStandardDao getStandardDao() {
		if (standardDao == null) {
			standardDao = new CmLimitStandardDao();
			standardDao.initDao(cfg, cmd, aspUser, user, conn);
		}
		return standardDao;
	}
	
	/**
	 * 限度基準コード取得
	 * @return 限度基準コードリスト
	 * @throws SQLException SQL例外処理が発生した場合
	 * @throws NoSuchFieldException 指定された名前のフィールドがクラスにはない場合
	 * @throws IllegalAccessException 基本となるメソッドが例外をスローする場合
	 * @throws MospException  MosP例外処理が発生した場合
	 */
	public String[][] getLimitStandardArray() throws SQLException, NoSuchFieldException, IllegalAccessException,
			MospException {
		// 情報の取得
		List<CmLimitStandardDto> list = getStandardDao().findAvailable();
		// 配列の作成
		String[][] aryLimitStandard = new String[list.size()][2];
		for (int i = 0; i < aryLimitStandard.length; i++) {
			aryLimitStandard[i][0] = list.get(i).getLimitCode();
			aryLimitStandard[i][1] = list.get(i).getLimitName();
		}
		return aryLimitStandard;
	}
	
	/**
	 * 時間外協定コード取得
	 * @param targetDate 対象年月日
	 * @return 時間外協定コード
	 * @throws NoSuchFieldException SQL例外処理が発生した場合
	 * @throws IllegalAccessException メソッドにアクセスできない場合
	 * @throws SQLException フィールドが見つからなかった場合
	 */
	public String[][] getOverTimeArray(Date targetDate) throws SQLException, IllegalAccessException,
			NoSuchFieldException {
		// 情報の取得
		List<String> list = getOverTimeDao().findForOverTimeCode(targetDate);
		// 配列の作成
		String[][] aryOverTime = new String[list.size()][2];
		for (int i = 0; i < aryOverTime.length; i++) {
			aryOverTime[i][0] = list.get(i);
			StringBuffer sb = new StringBuffer();
			sb.append(list.get(i));
			sb.append(CommonConst.NAM_COMMON_HALF_KANA_SPACE);
			sb.append(StringUtil.surroundRoundBracket(getOverTimeAgreementInfo(list.get(i), targetDate)
				.getWorkTypeName()));
			aryOverTime[i][1] = sb.toString();
		}
		return aryOverTime;
	}
	
	/**
	 * 休出協定コード取得
	 * @param targetDate 対象年月日
	 * @return 休出協定コード取得
	 * @throws SQLException SQL例外が発生した場合
	 * @throws IllegalAccessException メソッドにアクセスできない場合
	 * @throws NoSuchFieldException フィールドが見つからなかった場合
	 */
	public String[][] getWorkOnArray(Date targetDate) throws SQLException, IllegalAccessException, NoSuchFieldException {
		// 情報の取得
		List<String> list = getWorkOnDao().findForWorkOnCode(targetDate);
		// 配列の作成
		String[][] aryWorkOn = new String[list.size()][2];
		for (int i = 0; i < aryWorkOn.length; i++) {
			aryWorkOn[i][0] = list.get(i);
			StringBuffer sb = new StringBuffer();
			sb.append(list.get(i));
			sb.append(CommonConst.NAM_COMMON_HALF_KANA_SPACE);
			sb.append(StringUtil
				.surroundRoundBracket(getWorkOnAgreementInfo(list.get(i), targetDate).getWorkTypeName()));
			aryWorkOn[i][1] = sb.toString();
		}
		return aryWorkOn;
	}
	
}
