/*
 * 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.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

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.human.dao.MKihonDao;
import jp.mosp.human.dto.MKihonDto;

import jp.mosp.kintai.action.AttendanceTotalAction;

import jp.mosp.payroll.dao.CompileAmendmentDao;
import jp.mosp.payroll.dto.CompileAmendmentDto;
import jp.mosp.payroll.vo.AttendanceCalculateMenuVo;
import jp.mosp.payroll.vo.CompileAmendmentListVo;

public class CompileAmendmentListAction extends AttendanceTotalAction {

	// コマンド
	private static final String CMD_AMENDMENT_LIST_SHOW 		= "P1040";
	private static final String CMD_AMENDMENT_LIST_SEARCH 	= "P1041";
	public  static final String CMD_AMENDMENT_LIST_RE_SEARCH 	= "P1042";
	private static final String CMD_AMENDMENT_LIST_SORT 		= "P1043";

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

	public void action() throws Exception {
		// コネクション取得
		getConnection();
		// PAYROLL権限確認
		confirmPayrollAuth();
		// VOの取得
		CompileAmendmentListVo vo;
		Object obj = session.getAttribute(MospConst.ATT_FORMER_VO);
		if (obj instanceof CompileAmendmentListVo) {
			vo = (CompileAmendmentListVo) obj;
			vo.clearMessage();
			vo.clearErrField();
		} else {
			vo = new CompileAmendmentListVo();
		}
		vo.clearMessage();
		vo.clearErrField();
		vo.initVo(cfg, msg, cmd, aspUser, user);
		// VO及びフォワード先URLの設定
		setVo(vo);
		setUrl(vo.getRetUrl());
		session.setAttribute(MospConst.ATT_FORMER_VO, vo);
		// ユーザー情報取得
		getInfo(user.getUserId());
		// プルダウン取得
		setPulldownList(vo);
		// コマンド毎の処理
		if (cmd.equals(CMD_AMENDMENT_LIST_SHOW)) {
			// 表示
			// 集計年
			vo.setPltYear(String.valueOf(MospUtility.getYear(getCalcMonth())));
			// 集計月
			vo.setPltMonth(String.valueOf(MospUtility.getMonth(getCalcMonth())));
			// 検索履歴を初期値にセット
			vo.setSearchmode(CompileAmendmentListVo.SEARCH_OFF);
		} else if (cmd.equals(CMD_AMENDMENT_LIST_SEARCH)) {
			// 検索
			vo.setParams(request);
			serachEmployeeList(vo);
			vo.setFormerKey(vo.KEY_K_CODE);
			vo.setIsAscending(true);
			vo.initListInfo();
			// 検索履歴をありにセット
			vo.setSearchmode(CompileAmendmentListVo.SEARCH_ON);
		} else if (cmd.equals(CMD_AMENDMENT_LIST_RE_SEARCH)) {
			// 再検索
			session.removeAttribute(MospConst.ATT_DTO);
			if(vo.getSearchmode() == CompileAmendmentListVo.SEARCH_ON){
				serachEmployeeList(vo);
				vo.setPageButton();
				sortList(vo);
			} else {
				// 勤怠集計情報
				setCompileInfo(vo);
				serachEmployeeList(vo);
				vo.setFormerKey(vo.KEY_K_CODE);
				vo.setIsAscending(true);
				vo.initListInfo();
				// 検索履歴をありにセット
				vo.setSearchmode(CompileAmendmentListVo.SEARCH_ON);
				sortList(vo);
			}
		} else if (cmd.equals(CMD_AMENDMENT_LIST_SORT)) {
			// ソート
			sortList(key1, vo);
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}

	/**
	 * プルダウンリスト設定
	 * @param vo
	 * @throws Exception
	 */
	private void setPulldownList(CompileAmendmentListVo vo) throws Exception {
		// 勤怠承認機能確認
		if (isAttendanceApprovalFunction()) {
			vo.setMode(CompileAmendmentListVo.MODE_POSSIBLE);
		} else {
			vo.setMode(CompileAmendmentListVo.MODE_IMPOSSIBLE);		
		}
		// 所属リスト
		vo.aryPltSectionAll   = getSectionArrayAll();
		// 所属リストのセット
		if (hasCalculateAuth()) {
			vo.aryPltSection = util.addArrayFirstRowValue(
					getSectionArrayAll(),
					CommonConst.NAM_COMMON_STRING_INITIAL_VALUE,
					CommonConst.NAM_ALL_SECTION);
		} else {
			vo.aryPltSection = getSectionArrayForManager();
		}
		// 表示月
		Date current = getCalcMonth();
		// 年月リスト取得
		vo.aryPltYear  = util.getYearArray(MospUtility.getYear (current), 1, 1);
		vo.aryPltMonth = util.getMonthArray();
		// 未承認有無
		if (isAttendanceApprovalFunction()) {
			vo.aryPltApprovalFlag = util.addArrayFirstRowSpace(util.getExistenceArray());			
		} else {
			vo.aryPltApprovalFlag = util.getBlankArray();	
		}
		// 未計算有無
		vo.aryPltCompileFlag = util.addArrayFirstRowSpace(util.getExistenceArray());
	}

	/**
	 * 社員リスト検索
	 * @param vo Voインスタンス
	 * @throws Exception
	 */
	private void serachEmployeeList(CompileAmendmentListVo vo) throws Exception {
		// DBコネクションの取得
		if (conn == null) {
			getConnection();
		}
		// 集計月取得
		Date targetMonth = util.getFirstDateOfMonth(vo.getPltYear(), vo.getPltMonth());
		// 検索範囲取得
		int startDate = util.convDateToInteger(getStartDate(targetMonth));
		// 選択社員一覧検索
		MKihonDao mKihonDao = new MKihonDao();
		mKihonDao.initDao(cfg, cmd, aspUser, user, conn);
		List<MKihonDto> mKihonList = mKihonDao.findForCondition(
				vo.getTxtKCode(),
				vo.getTxtKName(),
				vo.getPltSection(),
				mKihon.getJCode(),
				mKihon.getKCode(),
				mospUser.getDataLevel(),
				startDate
		);
		// 勤怠集計検索
		CompileAmendmentDao mKintaiDao = new CompileAmendmentDao();
		mKintaiDao.initDao(cfg, cmd, aspUser, user, conn);
		List<CompileAmendmentDto> mKintaiList = new ArrayList<CompileAmendmentDto>();
		Iterator<MKihonDto> it = mKihonList.iterator();
		while (it.hasNext()) {
			MKihonDto mKihonDto = (MKihonDto) it.next();
			CompileAmendmentDto cAmendmentDto = mKintaiDao.findForCondition(
					mKihonDto.getKCode(),
					util.convDateToStringYearMonthShort(targetMonth),
					mKihonDto.getSCode()
			);
			// 未集計設定
			cAmendmentDto = setCompileFlag(cAmendmentDto, mKihonDto);
			// 未集計有無
			String isCompile = util.returnTrueIsOn(cAmendmentDto.getCompileflag());
			// 勤怠承認機能確認
			if (vo.getMode() == CompileAmendmentListVo.MODE_POSSIBLE) {
				// 未承認有無検索
				cAmendmentDto.setApprovalFlag(checkApproval(cAmendmentDto, targetMonth));
				// 未承認有無
				String isAllAprooved = util.returnTrueIsOff(cAmendmentDto.getApprovalFlag());
				// 未集計選択項目
				if (vo.getEscPltCompile().equals(isCompile)) {
					// 未承認選択項目
					if (vo.getEscPltApproval().equals(isAllAprooved)) {
						mKintaiList.add(cAmendmentDto);
					} 
					// 全件選択の場合
					else if (vo.getEscPltApproval().equals("")) {
						mKintaiList.add(cAmendmentDto);
					}
				} 
				// 未集計全件選択の場合
				else if (vo.getEscPltCompile().equals("")) {
					// 未承認選択項目
					if (vo.getEscPltApproval().equals(isAllAprooved)) {
						mKintaiList.add(cAmendmentDto);
					} 
					// 全件選択の場合				
					else if (vo.getEscPltApproval().equals("")) {
						mKintaiList.add(cAmendmentDto);
					}
				}
			} else {
				// 未集計選択、全件選択の場合
				if (vo.getEscPltCompile().equals(isCompile) ||
						vo.getEscPltCompile().equals("")) {
					mKintaiList.add(cAmendmentDto);
				}
			}
		}
		// VO設定
		vo.setFields(mKintaiList);
		// 選択年月
		vo.setHidSelectDate(util.convDateToStringYearMonthShort(targetMonth));
		// 対象が無かった場合のメッセージ設定
		if (vo.getAryCompile().length == 0) {
			vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_NO_DATA, ""));
		}
	}

	/**
	 * 未計算確認
	 * @param dto 対象DTO
	 * @param mKihonDto 人事基本情報DTO
	 * @return dto 対象DTO
	 * @throws Exception
	 */
	private CompileAmendmentDto setCompileFlag(CompileAmendmentDto dto, MKihonDto mKihonDto) throws Exception {
		if (dto == null) {
			dto = new CompileAmendmentDto();
			dto.setKCode(mKihonDto.getKCode());
			dto.setKName(mKihonDto.getSimei());
			dto.setSCode(mKihonDto.getSCode());
			// 未集計
			dto.setCompileflag(true);
		} else {
			// 集計済
			dto.setCompileflag(false);
		}
		return dto;
	}

	/**
	 * 勤怠集計情報のセット
	 * @param vo
	 * @throws Exception
	 */
	private void setCompileInfo(CompileAmendmentListVo vo) throws Exception {
		// 集計所属コード
		vo.setPltSection((String)request.getAttribute(AttendanceCalculateMenuVo.COMPILE_SECTION));
		// 集計社員コード
		vo.setTxtKCode((String)request.getAttribute(AttendanceCalculateMenuVo.COMPILE_K_CODE));
		// 集計年
		vo.setPltYear(String.valueOf(MospUtility.getYear(getCalcMonth())));
		// 集計月
		vo.setPltMonth(String.valueOf(MospUtility.getMonth(getCalcMonth())));
	}

	/**
	 * ソート
	 * @param key ソートキー
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private void sortList(String key, CompileAmendmentListVo vo) throws MospException {
		vo.sortList(key, getComparator(key, vo));
		vo.setFields(vo.getList());
	}

	/**
	 * ソート(VO内のキー情報でソート)
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private void sortList(CompileAmendmentListVo vo) throws MospException {
		vo.sortList(getComparator(vo.getFormerKey(), vo));
		vo.setFields(vo.getList());
	}

	/**
	 * 比較クラス取得
	 * @param key ソートキー
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private Comparator getComparator(String key, CompileAmendmentListVo vo) throws MospException {
		Comparator comp = null;
		if (key.equals(vo.KEY_K_CODE)) {
			comp = new CompKCode();
		} else if (key.equals(vo.KEY_K_NAME)) {
			comp = new CompKName();
		} else if (key.equals(vo.KEY_SECTION)) {
			comp = new CompSection();
		} else {
			throw new MospException(MospConst.EX_SORTKEY_INVALID);
		}
		return comp;
	}

	/**
	 * 社員コードによる比較クラス
	 */
	protected static class CompKCode implements Comparator, Serializable {
		private static final long serialVersionUID = 2785426316163131119L;
		public int compare(Object obj1, Object obj2) {
			CompileAmendmentDto dto1 = (CompileAmendmentDto)obj1;
			CompileAmendmentDto dto2 = (CompileAmendmentDto)obj2;
			return dto1.getKCode().compareTo(dto2.getKCode());
		}
	}

	/**
	 * 社員名による比較クラス
	 */
	protected static class CompKName implements Comparator, Serializable {
		private static final long serialVersionUID = 6920023209991067840L;
		public int compare(Object obj1, Object obj2) {
			CompileAmendmentDto dto1 = (CompileAmendmentDto)obj1;
			CompileAmendmentDto dto2 = (CompileAmendmentDto)obj2;
			return dto1.getKName().compareTo(dto2.getKName());
		}
	}

	/**
	 * 所属による比較クラス
	 */
	protected static class CompSection implements Comparator, Serializable {
		private static final long serialVersionUID = 8039660004898020825L;
		public int compare(Object obj1, Object obj2) {
			CompileAmendmentDto dto1 = (CompileAmendmentDto)obj1;
			CompileAmendmentDto dto2 = (CompileAmendmentDto)obj2;
			return dto1.getSCode().compareTo(dto2.getSCode());
		}
	}

}
