package jp.mosp.payroll.common.action;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
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.common.MospUtility;
import jp.mosp.common.common.ValidateUtility;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.TimeUtil;
import jp.mosp.common.utils.VariousUtil;
import jp.mosp.kintai.common.dao.MKihonDao;
import jp.mosp.kintai.common.dto.CmWorkTypeDto;
import jp.mosp.kintai.common.dto.MKihonDto;
import jp.mosp.kintai.common.part.KintaiCommonPart;
import jp.mosp.kintai.dao.MSyukkinboDao;
import jp.mosp.kintai.dto.MSyukkinboDto;
import jp.mosp.mospcommon.system.AgreementBaseInfo;
import jp.mosp.payroll.base.PayrollConst;
import jp.mosp.payroll.common.vo.SyukkinboImportCardVo;
import jp.mosp.payroll.dao.MImportFieldDao;
import jp.mosp.payroll.dto.MImportFieldDto;

import org.apache.commons.csv.CSVParser;

/**
 * @author koike
 *
 */
public class SyukkinboImportCardAction extends jp.mosp.kintai.common.action.AttendanceTotalAction {
	
	// コマンド
	private static final String	CMD_SHOW		= "P9050";
	private static final String	CMD_IMPORT		= "P9051";
	
	// フィールド
	/**
	 * 
	 */
	protected MKihonDao			mKihonDao;
	/**
	 * 
	 */
	protected MKihonDto			mKihonDto;
	/**
	 * 
	 */
	protected MSyukkinboDao		syukkinboDao;
	/**
	 * 
	 */
	protected int				late			= 0;
	/**
	 * 
	 */
	protected int				work			= 0;
	/**
	 * 
	 */
	protected int				leave			= 0;
	/**
	 * 
	 */
	protected int				over			= 0;
	/**
	 * 
	 */
	protected int				overPremium		= 0;
	/**
	 * 
	 */
	protected int				overNonPremium	= 0;
	/**
	 * 
	 */
	protected int				interval		= 0;
	/**
	 * 
	 */
	protected int				latenight		= 0;
	/**
	 * 
	 */
	protected int				holidaywork		= 0;
	/**
	 * 
	 */
	protected int				startTime		= 0;
	/**
	 * 
	 */
	protected int				quitTime		= 0;
	/**
	 * 
	 */
	protected int				workTime		= 0;
	/**
	 * 
	 */
	protected int				breakTime		= 0;
	/**
	 * 
	 */
	protected int				overStart		= 0;
	/**
	 * 
	 */
	protected int				overBreak		= 0;
	/**
	 * 
	 */
	protected int				allHoliday		= 0;
	/**
	 * 
	 */
	protected int				halfHoliday		= 0;
	/**
	 * 
	 */
	protected double			hoursPerDay		= 0;
	
	/**
	 * ヘッダ
	 */
	private String[]			aryImportHeaderItem;
	

	/**
	 * コンストラクタ
	 */
	public SyukkinboImportCardAction() {
		super();
		setNeedProcSeq(false);
		
	}
	
	/* (non-Javadoc)
	 * @see jp.mosp.common.common.BaseAction#getSpecificVo()
	 */
	@Override
	protected BaseVo getSpecificVo() {
		return new SyukkinboImportCardVo();
	}
	
	/**
	 * アクション
	 */
	public void action() throws Exception {
		// DBコネクション取得
		getConnection();
		// VO取得及び設定
		prepareVo();
		// 各表示項目取得
		setPulldownList();
		// コマンド毎の処理
		if (cmd.equals(CMD_SHOW)) {
			show();
		} else if (cmd.equals(CMD_IMPORT)) {
			importFile();
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}
	
	@Override
	public void show() throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		vo.setSelectICode(key1);
		aryImportHeaderItem = getTemplateItemArray();
		vo.setLblHeader(makeTemplateCSV().toString());
	}
	
	/**
	 * インポート
	 * @throws Exception
	 */
	private void importFile() throws Exception {
		aryImportHeaderItem = getTemplateItemArray();
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		// ファイル情報設定
		vo.setImportFile(multipartFieldList);
		// インポート
		importData();
		vo.initListInfo();
	}
	
	/**
	 * 表示用データ配列
	 * @throws Exception 例外処理が発生した場合
	 */
	private void setPulldownList() throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		vo.aryWorkType = getWorkTypeArrayNotDeleted();
		vo.aryHolidayReason = getReasonCodeArray(CommonConst.TID_LEAVE_REASON);
		vo.aryLateReason = getReasonCodeArray(CommonConst.TID_LATE_REASON);
		vo.aryLeaveEarlyReason = getReasonCodeArray(CommonConst.TID_LEAVE_EARLY_REASON);
	}
	
	/**
	 * テンプレート項目配列
	 * @return aryItem
	 * @throws Exception 例外処理が発生した場合
	 */
	private String[] getTemplateItemArray() throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		// DAOの準備
		MImportFieldDao dao = new MImportFieldDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		List<MImportFieldDto> list = dao.findForCondition(vo.getSelectICode());
		String[] aryItem = new String[list.size()];
		for (int i = 0; i < list.size(); i++) {
			aryItem[i] = StringUtil.getCodeName(list.get(i).getIField(), getImportFieldArray());
		}
		return aryItem;
	}
	
	/**
	 * インポート
	 * @throws Exception 例外処理が発生した場合
	 */
	private void importData() throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		// ファイル取得
		File file = getUploadFile(vo.getFilImportFile());
		String[] aryHeader;
		String[][] aryImportData = new String[0][0];
		// CSVファイル
		if (vo.getFilImportFile().getName().matches(".*" + ".csv" + ".*")) {
			// CSVパースファイル取得
			CSVParser csvp = parseCSVData(file);
			aryHeader = getCSVHeadData(csvp);
			aryImportData = csvp.getAllValues();
			br.close();
		} else {
			vo.addErrMessage(MospUtility.getMessage(msg, CommonConst.MSG_NO_CSV_DATA, ""));
			throw new MospException(MospConst.EX_PARAMS_INVALID);
		}
		// 検証済みリストの作成
		List<MSyukkinboDto> listImportData = getImportDataList(aryHeader, aryImportData);
		// 自動計算
		runAutoCalc(listImportData);
		// 登録処理
		int count = registImportData(listImportData);
		// コミット
		commit();
		// メッセージの設定
		vo.setMessage(MospUtility.getMessage(msg, CommonConst.MSG_NUMBER_OF_UPDATES, String.valueOf(count)));
		// VOに値をセット
		vo.setFields(listImportData);
	}
	
	/**
	 * テンプレートCSV出力内容
	 * @return sb テンプレートCSV
	 */
	private StringBuffer makeTemplateCSV() {
		// 帳票作成準備
		StringBuffer sb = new StringBuffer();
		// ヘッダー情報設定
		for (int i = 0; i < aryImportHeaderItem.length; i++) {
			// ヘッダー情報設定
			sb.append(getCsvData(aryImportHeaderItem[i]));
			// セパレータ設定
			if (i == aryImportHeaderItem.length - 1) {
				sb.append(CommonConst.STR_CSV_NEW_LINE);
			} else {
				sb.append(CommonConst.STR_CSV_SEPARATOR);
			}
		}
		return sb;
	}
	
	/**
	 * 検証済みインポート情報リスト作成
	 * @param aryHeader	 ヘッダー配列
	 * @param aryImportData インポート情報配列
	 * @return listData 検証済み出勤簿情報リスト
	 * @throws Exception 例外処理が発生した場合
	 */
	private List<MSyukkinboDto> getImportDataList(String[] aryHeader, String[][] aryImportData) throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		if (aryImportData == null) {
			vo.addErrMessage(MospUtility.getMessage(msg, CommonConst.MSG_NO_CSV_DATA, ""));
			aryImportData = new String[0][0];
		}
		
		List<MSyukkinboDto> listData = new ArrayList<MSyukkinboDto>();
		// ヘッダ確認
		if (StringUtil.checkArraysEquals(aryHeader, aryImportHeaderItem)) {
			for (int i = 0; i < aryImportData.length; i++) {
				MSyukkinboDto dto = new MSyukkinboDto();
				for (int j = 0; j < aryImportHeaderItem.length; j++) {
					if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KCODE)) {
						// 社員コードを半角へ統一
						dto.setKCode(StringUtil.toHankakuKana(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HIZUKE)) {
						String[] aryHizuke = getDateArray(aryImportData[i][j]);
						// 日付チェック
						if (ValidateUtility.chkDate(vo.getIntParam(aryHizuke[0]), vo.getIntParam(aryHizuke[1]) - 1, vo
							.getIntParam(aryHizuke[2]))) {
							dto.setHizuke(DateUtil.convStringDateFormatted(aryHizuke[0], aryHizuke[1], aryHizuke[2]));
						} else {
							dto.setHizuke("");
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SYJIKOKU)) {
						dto.setSyJikoku(convStringTimeFormatted(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KINMU)) {
						dto.setKinmu(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SHANKYUKB)) {
						if (aryImportData[i][j].equals("")
								|| aryImportData[i][j].equals(CommonConst.NUM_START_HALF_HOLIDAY_FLAG_OFF)
								|| aryImportData[i][j].equals(CommonConst.NUM_START_HALF_HOLIDAY_FLAG_ON)) {
							dto.setSHankyuKb(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KYUSYUKB)) {
						if (aryImportData[i][j].equals("")
								|| aryImportData[i][j].equals(CommonConst.NUM_WORK_ON_HOLIDAY_FLAG_OFF)
								|| aryImportData[i][j].equals(CommonConst.NUM_WORK_ON_HOLIDAY_FLAG_ON)) {
							dto.setKyusyuKb(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_TIRIYUU)) {
						dto.setTiRiyuu(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_TICOMENT)) {
						dto.setTiComent(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_TISYOUMEI)) {
						if (aryImportData[i][j].equals("") || aryImportData[i][j].equals("0")
								|| aryImportData[i][j].equals("1")) {
							dto.setTiSyoumei(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_TIJIKAN)) {
						dto.setTiJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_TAJIKOKU)) {
						dto.setTaJikoku(convStringTimeFormatted(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KINMUJI)) {
						dto.setKinmuJi(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KYUKEIJI)) {
						dto.setKyukeiJi(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_THANKYUKB)) {
						if (aryImportData[i][j].equals("")
								|| aryImportData[i][j].equals(CommonConst.NUM_QUIT_HALF_HOLIDAY_FLAG_OFF)
								|| aryImportData[i][j].equals(CommonConst.NUM_QUIT_HALF_HOLIDAY_FLAG_ON)) {
							dto.setTHankyuKb(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SORIYUU)) {
						dto.setSoRiyuu(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SOCOMENT)) {
						dto.setSoComent(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SOSYOUMEI)) {
						if (aryImportData[i][j].equals("") || aryImportData[i][j].equals("0")
								|| aryImportData[i][j].equals("1")) {
							dto.setSoSyoumei(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SOJIKAN)) {
						dto.setSoJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_ZAJIKAN)) {
						dto.setZaJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KSJIKAN)) {
						dto.setKsJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SNJIKAN)) {
						dto.setSnJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_SYOKJI)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setSyokuji(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_CYOKU1)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setCyoku1(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_CYOKU2)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setCyoku2(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_CYOKU3)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setCyoku3(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HOKA1)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setHoka1(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HOKA2)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setHoka2(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HOKA3)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setHoka3(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HOKA4)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setHoka4(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_HOKA5)) {
						if (aryImportData[i][j].equals("0") || aryImportData[i][j].equals("1")) {
							dto.setHoka5(vo.getIntParam(aryImportData[i][j]));
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KKRIYUU)) {
						dto.setKKRiyuu(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_DAIKYUJYU)) {
						String[] aryDaiKyuJyu = getDateArray(aryImportData[i][j]);
						// 日付チェック
						if (!aryImportData[i][j].equals("")
								&& ValidateUtility.chkDate(vo.getIntParam(aryDaiKyuJyu[0]), vo
									.getIntParam(aryDaiKyuJyu[1]) - 1, vo.getIntParam(aryDaiKyuJyu[2]))) {
							dto.setDaiKyuJyu(DateUtil.convStringDateFormatted(aryDaiKyuJyu[0], aryDaiKyuJyu[1],
									aryDaiKyuJyu[2]));
						} else {
							dto.setDaiKyuJyu("");
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KKCOMENT)) {
						dto.setKKComent(aryImportData[i][j]);
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KKSYOUMEI)) {
						if (aryImportData[i][j].equals("") || aryImportData[i][j].equals("0")
								|| aryImportData[i][j].equals("1")) {
							dto.setKKSyoumei(aryImportData[i][j]);
						}
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_KKJIKAN)) {
						dto.setKKJikan(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_NIJIKYU)) {
						dto.setNijiKyu(convStringTimeToIntegerTime(aryImportData[i][j]));
					} else if (aryImportHeaderItem[j].equals(PayrollConst.NAM_IMPORT_FIELD_NZAJIKAN)) {
						dto.setWarimasi1(convStringTimeToIntegerTime(aryImportData[i][j]));
					}
				}
				listData.add(dto);
			}
			if (aryImportData.length == 0) {
				vo.addErrMessage(MospUtility.getMessage(msg, CommonConst.MSG_NO_CSV_DATA, ""));
			}
		} else {
			vo.addErrMessage(MospUtility.getMessage(msg, CommonConst.MSG_INVALID_HEAD_TYPE, ""));
		}
		// インポートデータの検証
		listData = getVerifiedList(listData);
		return listData;
	}
	
	/**
	 * インポートデータの検証
	 * @param listData インポートデータ
	 * @return verifiedList 検証済みリスト
	 * @throws Exception 例外処理が発生した場合
	 */
	private List<MSyukkinboDto> getVerifiedList(List<MSyukkinboDto> listData) throws Exception {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		// DAO準備
		MSyukkinboDao dao = new MSyukkinboDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		// 検証済みリスト
		List<MSyukkinboDto> verifiedList = new ArrayList<MSyukkinboDto>();
		Iterator<MSyukkinboDto> it = listData.iterator();
		while (it.hasNext()) {
			MSyukkinboDto dto = it.next();
			StringBuffer code = new StringBuffer();
			// 人事情報検索
			findHumanBasisInfo(dto.getKCode(), false);
			if (!chkExistDto(mKihonDto)) {
				code.append(1);
			}
			// 日付チェック
			if (dto.getHizuke().equals("")) {
				code.append(2);
			}
			// 出勤簿情報検索
			if (chkExistDto(dao.findForKey(dto.getKCode(), dto.getHizuke()))) {
				code.append(3);
			}
			// 勤務形態チェック
			if (VariousUtil.checkNameExist(dto.getKinmu(), vo.aryWorkType)) {
				// 勤務形態が勤務形態である場合
				if (dto.getSyJikoku().equals("") || dto.getTaJikoku().equals("")) {
					code.append(4);
				}
			} else if (dto.getKinmu().equals(CommonConst.ATTENDANCE_TYPE_HOLIDAY)) {
				// 勤務形態が休暇である場合
				if (!VariousUtil.checkNameExist(dto.getKKRiyuu(), vo.aryHolidayReason)) {
					code.append(5);
				}
			} else if (!dto.getKinmu().equals(CommonConst.ATTENDANCE_TYPE_WEEK_HOLIDAY)) {
				// 勤務形態が週休でない場合
				code.append(6);
			}
			// 遅刻理由チェック
			if (!dto.getTiRiyuu().equals("") && !VariousUtil.checkNameExist(dto.getTiRiyuu(), vo.aryLateReason)) {
				code.append(7);
			}
			// 遅刻コメントチェック
			if (!ValidateUtility.chkRegex(".{0,50}", dto.getTiComent())) {
				code.append(8);
			}
			// 早退理由チェック
			if (!dto.getSoRiyuu().equals("") && !VariousUtil.checkNameExist(dto.getSoRiyuu(), vo.aryLeaveEarlyReason)) {
				code.append(9);
			}
			// 早退コメントチェック
			if (!ValidateUtility.chkRegex(".{0,50}", dto.getSoComent())) {
				code.append("a");
			}
			// 休暇コメントチェック
			if (!ValidateUtility.chkRegex(".{0,50}", dto.getKKComent())) {
				code.append("b");
			}
			// ファイル内重複チェック
			for (int i = 0; i < verifiedList.size(); i++) {
				if (verifiedList.get(i).getKCode().equals(dto.getKCode())
						&& verifiedList.get(i).getHizuke().equals(dto.getHizuke())) {
					code.append("c");
					break;
				}
			}
			// 検証結果からそれぞれ判断する。
			if (code.length() == 0) {
				String nowDate = DateUtil.getDateTime(DateUtil.getNowDate());
				// 正当な場合、必要な初期項目をセットする。
				dto.setNen(MospUtility.getYear(DateUtil.convStringDateToDate(dto.getHizuke())));
				dto.setTuki(MospUtility.getMonth(DateUtil.convStringDateToDate(dto.getHizuke())));
				dto.setHi(MospUtility.getDay(DateUtil.convStringDateToDate(dto.getHizuke())));
				dto.setSyozoku(getBelongSectionCode(dto.getKCode()));
				if (!dto.getSyJikoku().equals("")) {
					dto.setSyTimes(nowDate);
				}
				if (!dto.getTaJikoku().equals("")) {
					dto.setTaTimes(nowDate);
				}
				if (dto.getKinmu().equals(CommonConst.ATTENDANCE_TYPE_HOLIDAY)) {
					dto.setKKTimes(nowDate);
				}
				dto.setUpdtTimes(nowDate);
				dto.setSnRiyuu("0");
				// 検証済みリストへ追加
				verifiedList.add(dto);
			}
		}
		return verifiedList;
	}
	
	/**
	 * 登録処理
	 * @param listImportData 検証済みリスト
	 * @return insertCount 登録件数
	 * @throws Exception 例外処理が発生した場合
	 */
	private int registImportData(List<MSyukkinboDto> listImportData) throws Exception {
		// DAOの準備
		MSyukkinboDao dao = new MSyukkinboDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		// 登録件数
		int syukkinboCount = 0;
		// 回す回数
		int rev = 0;
		// 分割件数
		int div = 100;
		if (listImportData.size() % div == 0) {
			rev = listImportData.size() / div;
		} else {
			rev = listImportData.size() / div + 1;
		}
		for (int i = 0; i < rev; i++) {
			List<MSyukkinboDto> currentList = new ArrayList<MSyukkinboDto>();
			// リストをdiv件ごと分割する。
			for (int k = 0; k < div; k++) {
				int count = k + i * div;
				if (count >= listImportData.size()) {
					break;
				}
				MSyukkinboDto dto = listImportData.get(count);
				if (chkExistDto(dto)) {
					currentList.add(dto);
				} else {
					break;
				}
			}
			// リストを配列にセットする。
			MSyukkinboDto[] arySyukkinboData = new MSyukkinboDto[currentList.size()];
			for (int j = 0; j < currentList.size(); j++) {
				arySyukkinboData[j] = currentList.get(j);
			}
			// 登録処理
			syukkinboCount += dao.insert(arySyukkinboData);
		}
		return syukkinboCount;
	}
	
	/**
	 * インポートフィールドプルダウン取得
	 * @return インポートフィールドプルダウン用文字列配列
	 */
	private String[][] getImportFieldArray() {
		String[][] aryImportField = new String[37][2];
		aryImportField[0][0] = PayrollConst.CODE_IMPORT_FIELD_KCODE;
		aryImportField[1][0] = PayrollConst.CODE_IMPORT_FIELD_HIZUKE;
		aryImportField[2][0] = PayrollConst.CODE_IMPORT_FIELD_SYJIKOKU;
		aryImportField[3][0] = PayrollConst.CODE_IMPORT_FIELD_KINMU;
		aryImportField[4][0] = PayrollConst.CODE_IMPORT_FIELD_SHANKYUKB;
		aryImportField[5][0] = PayrollConst.CODE_IMPORT_FIELD_KYUSYUKB;
		aryImportField[6][0] = PayrollConst.CODE_IMPORT_FIELD_TIRIYUU;
		aryImportField[7][0] = PayrollConst.CODE_IMPORT_FIELD_TICOMENT;
		aryImportField[8][0] = PayrollConst.CODE_IMPORT_FIELD_TISYOUMEI;
		aryImportField[9][0] = PayrollConst.CODE_IMPORT_FIELD_TIJIKAN;
		aryImportField[10][0] = PayrollConst.CODE_IMPORT_FIELD_TAJIKOKU;
		aryImportField[11][0] = PayrollConst.CODE_IMPORT_FIELD_KINMUJI;
		aryImportField[12][0] = PayrollConst.CODE_IMPORT_FIELD_KYUKEIJI;
		aryImportField[13][0] = PayrollConst.CODE_IMPORT_FIELD_THANKYUKB;
		aryImportField[14][0] = PayrollConst.CODE_IMPORT_FIELD_SORIYUU;
		aryImportField[15][0] = PayrollConst.CODE_IMPORT_FIELD_SOCOMENT;
		aryImportField[16][0] = PayrollConst.CODE_IMPORT_FIELD_SOSYOUMEI;
		aryImportField[17][0] = PayrollConst.CODE_IMPORT_FIELD_SOJIKAN;
		aryImportField[18][0] = PayrollConst.CODE_IMPORT_FIELD_ZAJIKAN;
		aryImportField[19][0] = PayrollConst.CODE_IMPORT_FIELD_KSJIKAN;
		aryImportField[20][0] = PayrollConst.CODE_IMPORT_FIELD_SNJIKAN;
		aryImportField[21][0] = PayrollConst.CODE_IMPORT_FIELD_SYOKJI;
		aryImportField[22][0] = PayrollConst.CODE_IMPORT_FIELD_CYOKU1;
		aryImportField[23][0] = PayrollConst.CODE_IMPORT_FIELD_CYOKU2;
		aryImportField[24][0] = PayrollConst.CODE_IMPORT_FIELD_CYOKU3;
		aryImportField[25][0] = PayrollConst.CODE_IMPORT_FIELD_HOKA1;
		aryImportField[26][0] = PayrollConst.CODE_IMPORT_FIELD_HOKA2;
		aryImportField[27][0] = PayrollConst.CODE_IMPORT_FIELD_HOKA3;
		aryImportField[28][0] = PayrollConst.CODE_IMPORT_FIELD_HOKA4;
		aryImportField[29][0] = PayrollConst.CODE_IMPORT_FIELD_HOKA5;
		aryImportField[30][0] = PayrollConst.CODE_IMPORT_FIELD_KKRIYUU;
		aryImportField[31][0] = PayrollConst.CODE_IMPORT_FIELD_DAIKYUJYU;
		aryImportField[32][0] = PayrollConst.CODE_IMPORT_FIELD_KKCOMENT;
		aryImportField[33][0] = PayrollConst.CODE_IMPORT_FIELD_KKSYOUMEI;
		aryImportField[34][0] = PayrollConst.CODE_IMPORT_FIELD_KKJIKAN;
		aryImportField[35][0] = PayrollConst.CODE_IMPORT_FIELD_NIJIKYU;
		aryImportField[36][0] = PayrollConst.CODE_IMPORT_FIELD_NZAJIKAN;
		aryImportField[0][1] = PayrollConst.NAM_IMPORT_FIELD_KCODE;
		aryImportField[1][1] = PayrollConst.NAM_IMPORT_FIELD_HIZUKE;
		aryImportField[2][1] = PayrollConst.NAM_IMPORT_FIELD_SYJIKOKU;
		aryImportField[3][1] = PayrollConst.NAM_IMPORT_FIELD_KINMU;
		aryImportField[4][1] = PayrollConst.NAM_IMPORT_FIELD_SHANKYUKB;
		aryImportField[5][1] = PayrollConst.NAM_IMPORT_FIELD_KYUSYUKB;
		aryImportField[6][1] = PayrollConst.NAM_IMPORT_FIELD_TIRIYUU;
		aryImportField[7][1] = PayrollConst.NAM_IMPORT_FIELD_TICOMENT;
		aryImportField[8][1] = PayrollConst.NAM_IMPORT_FIELD_TISYOUMEI;
		aryImportField[9][1] = PayrollConst.NAM_IMPORT_FIELD_TIJIKAN;
		aryImportField[10][1] = PayrollConst.NAM_IMPORT_FIELD_TAJIKOKU;
		aryImportField[11][1] = PayrollConst.NAM_IMPORT_FIELD_KINMUJI;
		aryImportField[12][1] = PayrollConst.NAM_IMPORT_FIELD_KYUKEIJI;
		aryImportField[13][1] = PayrollConst.NAM_IMPORT_FIELD_THANKYUKB;
		aryImportField[14][1] = PayrollConst.NAM_IMPORT_FIELD_SORIYUU;
		aryImportField[15][1] = PayrollConst.NAM_IMPORT_FIELD_SOCOMENT;
		aryImportField[16][1] = PayrollConst.NAM_IMPORT_FIELD_SOSYOUMEI;
		aryImportField[17][1] = PayrollConst.NAM_IMPORT_FIELD_SOJIKAN;
		aryImportField[18][1] = PayrollConst.NAM_IMPORT_FIELD_ZAJIKAN;
		aryImportField[19][1] = PayrollConst.NAM_IMPORT_FIELD_KSJIKAN;
		aryImportField[20][1] = PayrollConst.NAM_IMPORT_FIELD_SNJIKAN;
		aryImportField[21][1] = PayrollConst.NAM_IMPORT_FIELD_SYOKJI;
		aryImportField[22][1] = PayrollConst.NAM_IMPORT_FIELD_CYOKU1;
		aryImportField[23][1] = PayrollConst.NAM_IMPORT_FIELD_CYOKU2;
		aryImportField[24][1] = PayrollConst.NAM_IMPORT_FIELD_CYOKU3;
		aryImportField[25][1] = PayrollConst.NAM_IMPORT_FIELD_HOKA1;
		aryImportField[26][1] = PayrollConst.NAM_IMPORT_FIELD_HOKA2;
		aryImportField[27][1] = PayrollConst.NAM_IMPORT_FIELD_HOKA3;
		aryImportField[28][1] = PayrollConst.NAM_IMPORT_FIELD_HOKA4;
		aryImportField[29][1] = PayrollConst.NAM_IMPORT_FIELD_HOKA5;
		aryImportField[30][1] = PayrollConst.NAM_IMPORT_FIELD_KKRIYUU;
		aryImportField[31][1] = PayrollConst.NAM_IMPORT_FIELD_DAIKYUJYU;
		aryImportField[32][1] = PayrollConst.NAM_IMPORT_FIELD_KKCOMENT;
		aryImportField[33][1] = PayrollConst.NAM_IMPORT_FIELD_KKSYOUMEI;
		aryImportField[34][1] = PayrollConst.NAM_IMPORT_FIELD_KKJIKAN;
		aryImportField[35][1] = PayrollConst.NAM_IMPORT_FIELD_NIJIKYU;
		aryImportField[36][1] = PayrollConst.NAM_IMPORT_FIELD_NZAJIKAN;
		return aryImportField;
	}
	
	/**
	 * 人事基本情報用DAO準備
	 */
	protected void prepareHumanBasisDao() {
		// DAO準備
		if (mKihonDao != null) {
			return;
		}
		mKihonDao = new MKihonDao();
		mKihonDao.initDao(cfg, cmd, aspUser, user, conn);
	}
	
	/**
	 * 人事基本情報取得
	 * @param kCode       社員コード
	 * @param isForUpdate アップデート用フラグ
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	protected void findHumanBasisInfo(String kCode, boolean isForUpdate) throws SQLException, IllegalAccessException,
			NoSuchFieldException {
		// 人事基本情報用DAO準備
		prepareHumanBasisDao();
		// 現在の情報を取得
		if (isForUpdate) {
			mKihonDto = mKihonDao.findForUpdate(kCode);
		} else {
			mKihonDto = mKihonDao.findForKey(kCode);
		}
	}
	
	/**
	 * 日付取得
	 * @param date 対象日付
	 * @return 日付配列
	 */
	private String[] getDateArray(String date) {
		String[] aryDate = new String[3];
		if (date.indexOf("/") != -1) {
			// dateがyyyy/mm/ddである場合
			aryDate = date.split("/", 3);
		} else if (date.indexOf("-") != -1) {
			// dateがyyyy-mm-ddである場合
			aryDate = date.split("-", 3);
		} else if (date.length() == 8) {
			// dateがyyyymmddである場合
			aryDate[0] = date.substring(0, 4);
			aryDate[1] = date.substring(4, 6);
			aryDate[2] = date.substring(6, date.length());
		}
		return aryDate;
	}
	
	/**
	 * 時刻変換
	 * @param time 時刻(HH:MM)
	 * @return HH:MM
	 */
	private String convStringTimeFormatted(String time) {
		String formattedTime = "";
		if (time.indexOf(CommonConst.STR_TIME_SEPARATOR) != -1) {
			formattedTime = TimeUtil.convIntegerTimeToStringTime(TimeUtil.convStringTimeToIntegerTime(time));
		}
		return formattedTime;
	}
	
	/**
	 * 時間変換
	 * @param time 対象時間
	 * @return 経過分数
	 */
	private int convStringTimeToIntegerTime(String time) {
		// VO取得
		SyukkinboImportCardVo vo = (SyukkinboImportCardVo)getVo();
		int intTime = 0;
		if (time.indexOf(CommonConst.STR_TIME_SEPARATOR) != -1) {
			// timeがHH:MMである場合
			intTime = TimeUtil.convStringTimeToIntegerTime(time);
		} else {
			// timeが分単位である場合
			intTime = vo.getIntParam(time);
		}
		return intTime;
	}
	
	/**
	 * 自動計算メソッド
	 * @param list
	 * @throws Exception
	 */
	private void runAutoCalc(List<MSyukkinboDto> list) throws Exception {
		// 自動計算フラグ有りのみ
		if (getMosPCode(CommonConst.TID_WORK_SYSTEM, CommonConst.TCD_AUTOMATIC_CALCULATION)[2].equals("0")) {
			Iterator it = list.iterator();
			while (it.hasNext()) {
				MSyukkinboDto dto = (MSyukkinboDto)it.next();
				// 対象日取得
				Date targetDay = DateUtil.convStringDateToDate(dto.getHizuke());
				// 勤怠日データ取得
				getAttendanceDay(dto.getKCode(), targetDay);
				if (KintaiCommonPart.isHoliday(dto)) {
					// 全休休暇時間
					dto.setKKJikan(allHoliday);
				} else {
					// 初期化
					late = 0;
					work = 0;
					leave = 0;
					over = 0;
					overPremium = 0;
					overNonPremium = 0;
					interval = 0;
					latenight = 0;
					holidaywork = 0;
					// 週休以外
					if (!KintaiCommonPart.isWeekHoliday(dto)) {
						// 休憩時間に入力された値をセット
						interval = dto.getKyukeiJi();
						// 勤務形態から規定時刻を取得
						getWorkTypeInfo(dto.getKinmu());
						// 出勤時刻算出
						int start = TimeUtil.convStringTimeToIntegerTime(dto.getSyJikoku());
						// 退勤時刻算出
						int quit = TimeUtil.convStringTimeToIntegerTime(dto.getTaJikoku());
						boolean shankyukbn = KintaiCommonPart.isStartHalfHoliday(dto.getSHankyuKb());
						boolean kyusyukbn = KintaiCommonPart.isWorkOnHoliday(dto.getKyusyuKb());
						boolean thankyukbn = KintaiCommonPart.isQuitHalfHoliday(dto.getTHankyuKb());
						// 出勤項目の計算
						getCalcStartTime(start, shankyukbn, kyusyukbn);
						// 遅刻時間セット
						dto.setTiJikan(late);
						// 退勤項目の計算
						getCalcQuitTime(start, quit, (shankyukbn || thankyukbn));
						// 勤務時間セット
						dto.setKinmuJi(work);
						// 早退時間セット
						dto.setSoJikan(leave);
						// 残業時間セット
						dto.setZaJikan(over);
						dto.setWarimasi1(overNonPremium);
						// 休憩時間セット
						dto.setKyukeiJi(interval);
						// 深夜時間セット
						dto.setSnJikan(latenight);
						// 休出時間セット
						if (kyusyukbn) {
							dto.setKsJikan(holidaywork);
						} else {
							dto.setKsJikan(0);
						}
					}
				}
			}
		}
	}
	
	/**
	 * 勤怠日データ取得
	 * @param kCode       対象社員コード
	 * @param targetDay 対象日
	 * @throws Exception 例外処理が発生した場合
	 */
	protected void getAttendanceDay(String kCode, Date targetDay) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 検索範囲取得
		String attendanceDate = MospUtility.getDateString(targetDay, CommonConst.FORMAT_DATE);
		// 出勤簿用DAO準備 
		prepareMSyukkinboDao();
		// 月一覧の取得
		attendanceList = syukkinboDao.findForCondition(kCode, attendanceDate);
		// 勤怠情報設定
		setHours(kCode, targetDay);
	}
	
	/**
	 * 出勤項目の計算
	 * @param start 出勤時刻(int)
	 * @param isStartHalf 出勤時半休の場合 true
	 * @param isHolidayWork 休出の場合true
	 */
	protected void getCalcStartTime(int start, boolean isStartHalf, boolean isHolidayWork) {
		if (isStartHalf | isHolidayWork) {
			late = 0;
		} else {
			late = setLateTimes(start);
		}
	}
	
	/**
	 * 退勤項目の計算
	 * @param start 出勤時刻
	 * @param quit 退勤時刻
	 * @param isHalf 出勤時半休、退勤時半休の場合true
	 */
	protected void getCalcQuitTime(int start, int quit, boolean isHalf) {
		// 勤務時間
		work = setWorkTimes(start, quit);
		leave = setLeaveEarlyTimes(quit);
		if (isHalf) {
			leave = 0;
		}
		over = setOverTimes(isHalf);
		interval = setIntervalTimes();
		latenight = setLateNightTimes(quit);
		holidaywork = setHolidayWork();
		
		overNonPremium = setOverNonPremiumTimes();
		overPremium = setOverPremiumTimes();
	}
	
	/**
	 * 出勤簿用DAO準備
	 * @throws Exception 例外処理が発生した場合
	 */
	protected void prepareMSyukkinboDao() throws Exception {
		// DAO準備
		if (syukkinboDao != null) {
			return;
		}
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		syukkinboDao = new MSyukkinboDao();
		syukkinboDao.initDao(cfg, cmd, aspUser, user, conn);
	}
	
	/**
	 * 日集計データ時間設定
	 * @param kCode 社員コード
	 * @param targetDay 対象年月日
	 * @throws Exception 例外処理が発生した場合
	 */
	protected void setHours(String kCode, Date targetDay) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 勤怠情報設定
		setCalcParam();
		// 労働時間設定
		setPrescribedHours(kCode, targetDay);
		// 勤務形態マスタ設定
		part().worktype().getWorkTypeMap();
	}
	
	/**
	 * 遅刻時間計算
	 * @param start 出勤時刻
	 * @return	int	遅刻時間
	 */
	private int setLateTimes(int start) {
		// 出勤時刻 - 標準出勤時刻
		int latemin = start - startTime;
		// 遅刻のときは調整計算(単位時間を加算)5分の場合計算結果が0分になるので最低でも単位時間とする
		if ((latemin < inputUnit) && (startTime < start)) {
			latemin = inputUnit;
		}
		if (latemin > 0) {
			// 丸め
			latemin -= latemin % inputUnit;
		}
		if (latemin < 0) {
			latemin = 0;
		}
		return latemin;
	}
	
	/**
	 * 勤務時間計算
	 * @param start 出勤時刻
	 * @param quit 退勤時刻
	 * @return	workmin
	 */
	private int setWorkTimes(int start, int quit) {
		// 退社時刻 - 出勤時刻		
		int workmin = quit - start;
		// 丸め
		workmin -= workmin % inputUnit;
		return workmin;
	}
	
	/**
	 * 早退時間計算
	 * @param quit 退勤時刻
	 * @return	leavemin
	 */
	private int setLeaveEarlyTimes(int quit) {
		// 標準退社時刻 - 退社時刻
		int leavemin = quitTime - quit;
		// 勤務時間 < 標準勤務時間
		if (work < workTime) {
			// 丸め
			leavemin -= leavemin % inputUnit;
		}
		if (leavemin < 0) {
			leavemin = 0;
		}
		return leavemin;
	}
	
	/**
	 * 残業時間計算
	 * @param isHalf 出勤時半休、退勤時半休の場合true
	 * @return	overmin
	 */
	private int setOverTimes(boolean isHalf) {
		// 遅刻時間 + 勤務時間
		int worktimes = late + work;
		// 残業時間
		int overmin = 0;
		// 半休調整
		if (isHalf) {
			worktimes -= halfHoliday;
		}
		// 勤務対象時間 > 標準残業計算開始時間
		if (worktimes > overStart) {
			// 勤務対象時間 - 標準勤務時間 - 残業休憩
			overmin = worktimes - workTime - overBreak;
			if (overmin < 0) {
				overmin = 0;
			}
		}
		return overmin;
	}
	
	/**
	 * 休憩時間計算
	 * @return	intervalmin
	 */
	private int setIntervalTimes() {
		int intervalmin = 0;
		// 標準休憩  5時間以上
		if (work > 300) {
			intervalmin = breakTime;
		}
		// 残業休憩
		if (over > 0) {
			intervalmin += overBreak;
		}
		return intervalmin;
	}
	
	/**
	 * 深夜時間計算
	 * @param quit 退勤時間
	 * @return	latenightmin
	 */
	private int setLateNightTimes(int quit) {
		// 退社時刻 - 標準深夜開始時刻
		int latenightmin = quit - lateNightStart;
		// 丸め
		latenightmin -= latenightmin % inputUnit;
		// 限度調整
		if (latenightmin > (lateNightEnd - lateNightStart)) {
			latenightmin = lateNightEnd - lateNightStart;
		}
		if (latenightmin < 0) {
			latenightmin = 0;
		}
		return latenightmin;
	}
	
	/**
	 * 休出時間計算
	 * @return	holiwork
	 */
	private int setHolidayWork() {
		int holiwork = work - interval;
		return holiwork;
	}
	
	/**
	 * 割増なし残業時間計算
	 * @return overNonPremiumMin
	 */
	private int setOverNonPremiumTimes() {
		// 割増なし残業時間
		int overNonPremiumMin = 0;
		// 残業時間が0分より長い場合
		if (over > 0) {
			// 割増なし残業時間 = 一日所定労働時間 + 標準休憩時間 - 標準勤務時間
//			overNonPremiumMin = hoursPerDay + breakTime - workTime;
			// 割増なし残業時間 = 一日所定労働時間 + 休憩時間 - 残業休憩時間 - 標準勤務時間
			overNonPremiumMin = (int)(hoursPerDay + interval - overBreak - workTime);
			if (overNonPremiumMin > over) {
				overNonPremiumMin = over;
			} else if (overNonPremiumMin < 0) {
				overNonPremiumMin = 0;
			}
		}
		return overNonPremiumMin;
	}
	
	/**
	 * 割増あり残業時間計算
	 * @return overPremiumMin
	 */
	private int setOverPremiumTimes() {
		// 割増あり残業時間 = 残業時間 - 割増なし残業時間
		int overPremiumMin = over - overNonPremium;
		return overPremiumMin;
	}
	
	/**
	 * 1日所定労働時間取得
	 * @param kCode 
	 * @param targetDay 
	 * @throws Exception 例外処理が発生した場合
	 */
	@SuppressWarnings("static-access")
	protected void setPrescribedHours(String kCode, Date targetDay) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 取得済確認
		/*
		if (hoursPerDay != 0) {
			return;
		}
		*/
		// M_CODEから値を取得
		//String[] aryConf = getMosPCode(CommonConst.TID_STATUTORY, CommonConst.TCD_STATUTORY_HOUR);
		AgreementBaseInfo laborAgreement = part().laborAgreement().getUserLaborAgreement(kCode, targetDay);
		
		// 値の設定
		//hoursPerDay = Double.parseDouble(aryConf[2]);
		hoursPerDay = part().laborAgreement().getPrescribedTime(laborAgreement) / 60;
	}
	
	/**
	 * 勤務形態別情報設定
	 * @param shiftcode
	 * @throws Exception 例外処理が発生した場合
	 */
	protected void getWorkTypeInfo(String shiftcode) throws Exception {
		// リスト
		Map<String, CmWorkTypeDto> workTypeMap;
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		workTypeMap = part().worktype().getWorkTypeMap();
		// 勤務形態情報取得
		CmWorkTypeDto dto = workTypeMap.get(shiftcode);
		startTime = dto.getStartTime();
		quitTime = dto.getQuitTime();
		workTime = dto.getWorkTime();
		breakTime = dto.getBreakTime();
		overStart = dto.getOverStart();
		overBreak = dto.getOverBreak();
	}
	
}
