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 org.apache.commons.csv.CSVParser;

import jp.mosp.common.CommonConst;
import jp.mosp.common.action.AttendanceTotalAction;
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.part.KintaiCommonPart;
import jp.mosp.human.dao.MKihonDao;
import jp.mosp.human.dto.MKihonDto;
import jp.mosp.kintai.dao.MSyukkinboDao;
import jp.mosp.kintai.dto.MSyukkinboDto;
import jp.mosp.payroll.base.PayrollConst;
import jp.mosp.payroll.common.vo.TimeRecordImportCardVo;
import jp.mosp.payroll.dao.MImportFieldDao;
import jp.mosp.payroll.dto.MImportFieldDto;
import jp.mosp.system.dto.MWorkTypeDto;

public class TimeRecordImportCardAction extends AttendanceTotalAction {

	// コマンド
	private static final String CMD_SHOW		= "P9060";
	private static final String CMD_IMPORT	= "P9061";

	// フィールド
	protected MKihonDao					mKihonDao;
	protected MKihonDto					mKihonDto;

	protected MSyukkinboDao				mSyukkinboDao;

	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 TimeRecordImportCardAction() {
		super();
		setNeedProcSeq(false);

	}

	/* (non-Javadoc)
	 * @see jp.mosp.common.common.BaseAction#getSpecificVo()
	 */
	@Override
	protected BaseVo getSpecificVo() {
		return new TimeRecordImportCardVo();
	}

	/**
	 * アクション
	 */
	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);
		}
	}

	private void show() throws Exception {
		// VO取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)getVo();
		vo.setSelectICode(key1);
		aryImportHeaderItem = getTemplateItemArray();
		vo.setLblHeader(makeTemplateCSV().toString());
	}

	/**
	 * インポート
	 * @throws Exception
	 */
	private void importFile() throws Exception {
		aryImportHeaderItem = getTemplateItemArray();
		// VO取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)getVo();
		// ファイル情報設定
		vo.setImportFile(multipartFieldList);
		// インポート
		importData();
		vo.initListInfo();
	}

	/**
	 * 表示用データ配列
	 * @throws Exception
	 */
	private void setPulldownList() throws Exception {
		// VO取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)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取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)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] = util.getCodeName(list.get(i).getIField(), getImportFieldArray());
		}
		return aryItem;
	}

	/**
	 * インポート
	 * @throws Exception
	 */
	private void importData() throws Exception {
		// VO取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)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取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)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 (util.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(util.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(util.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(util.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取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)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 = (MSyukkinboDto) 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 (util.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 (!util.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("")
					&& !util.checkNameExist(dto.getTiRiyuu(), vo.aryLateReason)
			) {
				code.append(7);
			}
			// 遅刻コメントチェック
			if (!ValidateUtility.chkRegex(".{0,50}", dto.getTiComent())) {
				code.append(8);
			}
			// 早退理由チェック
			if (!dto.getSoRiyuu().equals("")
					&& !util.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 = util.getDateTime(util.getNowDate());
				// 正当な場合、必要な初期項目をセットする。
				dto.setNen		(MospUtility.getYear	(util.convStringDateToDate(dto.getHizuke())));
				dto.setTuki		(MospUtility.getMonth	(util.convStringDateToDate(dto.getHizuke())));
				dto.setHi		(MospUtility.getDay		(util.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 timeRecordCount = 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[] aryTimeRecordData = new MSyukkinboDto[currentList.size()];
			for (int j = 0; j < currentList.size(); j++) {
				aryTimeRecordData[j] = currentList.get(j);
			}
			// 登録処理
			timeRecordCount += dao.insert(aryTimeRecordData);
		}
		return timeRecordCount;
	}

	/**
	 * インポートフィールドプルダウン取得
	 * @param table インポートテーブルコード
	 * @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 = util.convIntegerTimeToStringTime(util.convStringTimeToIntegerTime(time));
		}
		return formattedTime;
	}

	/**
	 * 時間変換
	 * @param time 対象時間
	 * @return 経過分数
	 */
	private int convStringTimeToIntegerTime(String time) {
		// VO取得
		TimeRecordImportCardVo vo = (TimeRecordImportCardVo)getVo();
		int intTime = 0;
		if (time.indexOf(CommonConst.STR_TIME_SEPARATOR) != -1) {
			// timeがHH:MMである場合
			intTime = util.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 = util.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();
						// 勤務形態から規定時刻を取得
						getWork_TypeInfo(dto.getKinmu());
						// 出勤時刻算出
						int start = util.convStringTimeToIntegerTime(dto.getSyJikoku());
						// 退勤時刻算出
						int quit = util.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準備 
		prepareMTimeRecordDao();
		// 月一覧の取得
		attendanceList	= mSyukkinboDao.findForCondition(kCode, attendanceDate);
		// 勤怠情報設定
		setHours();	
	}

	/**
	 * 出勤項目の計算
	 * @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 prepareMTimeRecordDao() throws Exception {
		// DAO準備
		if (mSyukkinboDao !=null) {
			return;
		}
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		mSyukkinboDao = new MSyukkinboDao();
		mSyukkinboDao.initDao(cfg, cmd, aspUser, user, conn);
	}

	/**
	 * 日集計データ時間設定
	 * @throws Exception 
	 */
	protected void setHours() throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 勤怠情報設定
		setCalcParam();
		// 労働時間設定
		setPrescribedHours();
		// 勤務形態マスタ設定
		setWorkTypeMap();
	}

	/**
	 * 遅刻時間計算
	 * @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;
	}

	/**
	 * 早退時間計算
	 * @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;
	}

	/**
	 * 深夜時間計算
	 * @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日所定労働時間取得
	 * @throws Exception 
	 */
	protected void setPrescribedHours() throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 取得済確認
		if (hoursPerDay != 0) {
			return;
		}
		// M_CODEから値を取得
		String[] aryConf = getMosPCode(CommonConst.TID_STATUTORY, CommonConst.TCD_STATUTORY_HOUR);
		// 値の設定
		hoursPerDay = Double.parseDouble(aryConf[2]);
	}

	/**
	 * 勤務形態別情報設定
	 * @param shiftcode
	 * @throws Exception 
	 */
	protected void getWork_TypeInfo(String shiftcode) throws Exception {
		// リスト
		Map<String, MWorkTypeDto> workTypeMap;
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		workTypeMap = getWorkTypeMap();
		// 勤務形態情報取得
		MWorkTypeDto dto = workTypeMap.get(shiftcode);
		startTime 	= dto.getStartTime();
		quitTime 	= dto.getQuitTime();
		workTime 	= dto.getWorkTime();
		breakTime	= dto.getBreakTime();
		overStart	= dto.getOverStart();
		overBreak	= dto.getOverBreak();
	}

}
