package jp.mosp.human.action;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;


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.human.vo.HumanCalcVo;
import jp.mosp.legal.LegalConst;
import jp.mosp.payroll.base.PayrollConst;
import jp.mosp.payroll.dao.CmBankDao;
import jp.mosp.payroll.dao.CmBranchDao;
import jp.mosp.payroll.dao.CmCompanyDao;
import jp.mosp.payroll.dto.CmBankDto;
import jp.mosp.payroll.dto.CmBranchDto;
import jp.mosp.payroll.dto.CmCommutationDto;
import jp.mosp.payroll.dto.CmIncomeTaxDto;
import jp.mosp.payroll.dto.CmMidwayEnterDto;
import jp.mosp.payroll.dto.CmPaymentMeansDto;
import jp.mosp.payroll.dto.CmResidenceTaxDto;
import jp.mosp.payroll.dto.CmSocInsuranceDto;
import jp.mosp.payroll.dto.CmUnitAmountDto;

public class HumanCalcAction extends PayrollHumanAction {

	// コマンド
	public  static final String CMD_HUMAN_CALC_SELECT = "U4150";
	private static final String CMD_HUMAN_CALC_INSERT = "U4151";
	private static final String CMD_HUMAN_CALC_UPDATE = "U4152";
	public  static final String CMD_HUMAN_CALC_TAB    = "U4153";

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

	/* (non-Javadoc)
	 * @see jp.mosp.common.common.BaseAction#getSpecificVo()
	 */
	@Override
	protected BaseVo getSpecificVo() {
		return new HumanCalcVo();
	}
	
	/**
	 * アクション
	 */
	public void action() throws Exception {
		// DBコネクション取得
		getConnection();
		// HUMAN権限確認
		confirmHumanAuth();
		// VO取得及び設定
		prepareVo();
		HumanCalcVo vo = (HumanCalcVo)getVo();
		// 銀行マスタ、支店マスタデータ作成
		convFinanceData(cfg.getProperty(MospConst.PPT_APP_DOCBASE) + PayrollConst.JS_FINANCE, false);
		// プルダウン設定
		setPulldown(vo);

		// コマンド毎の処理
		if (cmd.equals(CMD_HUMAN_CALC_SELECT)) {
			// パラメータ取得
			vo.setParams(request);
			// ボタン内容設定
			setListButton(vo);
			if (!vo.getTxtChangeKCode().equals("")) {
				// 表示(社員コードで情報を検索)
				select(vo);
			} else {
				setNextCmd("U4120");
			}
			// セッションにDTOをセット
			//session.setAttribute(MospConst.ATT_DTO, aryDto);
		} else if (cmd.equals(CMD_HUMAN_CALC_INSERT)) {
			// パラメータ取得
			vo.setParams(request);
			// ボタン内容設定
			setListButton(vo);
			// 更新
			regist(vo, false);
			// 検索
			select(vo);
			// セッションにDTOをセット
			//session.setAttribute(MospConst.ATT_DTO, aryDto);
		} else if (cmd.equals(CMD_HUMAN_CALC_UPDATE)) {
			// パラメータ取得
			vo.setParams(request);
			// ボタン内容設定
			setListButton(vo);
			// 更新
			regist(vo, false);
			// 検索
			select(vo);
			// セッションにDTOをセット
			//session.setAttribute(MospConst.ATT_DTO, aryDto);
		} else if (cmd.equals(CMD_HUMAN_CALC_TAB)) {
			// パラメータ取得
			vo.setParams(request);
			// ボタン内容設定
			setListButton(vo);
			// 情報設定
			vo.setHidCalcCurrentTab(key2);
			vo.setTxtChangeKCode(key1);
			// 表示(社員コードで情報を検索)
			select(vo);
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}
	
	
	/**
	 * プルダウン設定
	 * @param vo 対象VO
	 * @throws Exception
	 */
	public void setPulldown(HumanCalcVo vo) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// プルダウン設定
		if (vo.aryPltCoBank != null) {
			return;
		}
		vo.aryPltEra       = getCodeArray(PayrollConst.TID_JAPANESE     );
		vo.aryPltShortYear = getYearArray(1, 0, PayrollConst.TIME_SHOWA_LONG);
		vo.aryPltMonth     = getMonthArray();
		vo.aryPltDay       = getDayArray();
		vo.aryPltCoBank    = getCoBankArray();
		vo.aryPltAccountType       = getCodeArray(PayrollConst.TID_ACCOUNT_TYPE );
		vo.aryPltPaymentMeans      = getCodeArray(PayrollConst.TID_PAYMENT_MEANS);
		vo.aryPltAmountType        = PayrollConst.getAmountTypeArray()           ;
		vo.aryPltAmountTypeForRest = PayrollConst.getAmountTypeArrayForRest()    ;
		vo.aryPltPaymentInterval   = getCodeArray(PayrollConst.TID_PAY_INTERVAL );
		vo.aryPltLumpMonthlyType   = getCodeArray(PayrollConst.TID_LUMP_TYPE    );
		vo.aryPltPenDependentType  = LegalConst.PENSION_INSURED_ARRAY         ;
		vo.aryPltIncomeTaxType     = LegalConst.INCOME_TAX_ARRAY              ;
		vo.aryPltAdjustmentType    = LegalConst.ADJUSTMENT_ARRAY              ;
		vo.aryPltHandicapType      = LegalConst.HANDICAP_ARRAY                ;
		vo.aryPltWidowType         = LegalConst.WIDOW_ARRAY                   ;
		vo.aryPltStudentType       = LegalConst.STUDENT_ARRAY                 ;
		vo.aryPltSpouseIntendType  = LegalConst.SPOUSE_INTEND_ARRAY           ;
		vo.aryPltLiveWithType      = LegalConst.LIVE_WITH_ARRAY               ;
		vo.aryPltSpouseType        = LegalConst.SPOUSE_ARRAY                  ;
		vo.aryPltDependentType     = LegalConst.DEPENDENT_ARRAY               ;
		vo.aryPltPensionType       = LegalConst.PENSION_ARRAY                 ;
		vo.aryPltParttimeType      = LegalConst.PARTTIME_ARRAY                ;
		vo.aryPltEmployeeType      = LegalConst.EMPLOYEE_ARRAY                ;
		vo.aryPltCalcInsType       = LegalConst.CALC_INS_ARRAY                ;
		vo.aryPltNursingInsType    = LegalConst.NURSING_INS_ARRAY             ;
		vo.aryPltCalcUnemployType  = LegalConst.CALC_UNEMPLOY_ARRAY           ;
		vo.aryPltBonusHealthType   = LegalConst.BONUS_HEALTH_ARRAY            ;
		vo.aryPltBounsPensionType  = LegalConst.BONUS_PENSION_ARRAY           ;
		vo.aryPltHealthLostType    = LegalConst.HEALTH_LOST_ARRAY             ;
		vo.aryPltPensionLostType   = LegalConst.PENSION_LOST_ARRAY            ;
		vo.aryPltUnemployLostType  = LegalConst.UNEMPLOY_LOST_ARRAY           ;
		vo.aryPltMidwayType        = LegalConst.MIDWAY_ENTER_ARRAY            ;
		
		// 和暦設定取得
		vo.listConf = getConfList(PayrollConst.CONF_ID_JP_IMP_CAL);
		// JSに譲渡する配列設定
		//vo.setJSArray();
		
	}
	
	/**
	 * データ表示
	 * @param vo 対象VO
	 * @throws Exception
	 */
	public void select(HumanCalcVo vo) throws Exception {
		// 表示(社員コードで情報を検索)
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 選択社員人事給与情報取得
		getSelectedEmployeeBasis(vo);
		// 人事給与情報取得
		findHumanCalcInfo(vo.getLblKCode(), false);
		// 人事管理情報取得
		findHumanPersonnelInfo(vo.getLblKCode(), false);
		// 支給方法、口座名、フリガナ設定
		getHolderName(vo);
		// VO初期化
		vo.initFields();
		vo.setTxtChangeKCode(vo.getLblKCode());
		// 保険料率設定
		CmCompanyDao cmCompanyDao = new CmCompanyDao();
		cmCompanyDao.initDao(cfg, cmd, aspUser, user, conn);
		vo.setPremiumRatio(cmCompanyDao.findAll());
		// 人事情報設定
		vo.setFields(
				cmSocInsuranceDto,
				cmResidenceTaxDto, 
				cmIncomeTaxDto   ,
				cmMidwayEnterDto ,
				listPaymentMeans ,
				listCommutation  ,
				listUnitAmount   ,
				aryUnitType
		);
		// 銀行名設定
		setFinanceName(vo);
		// 排他情報設定
		String editor = setExclusive(PayrollConst.EXC_HUMAN_CA_PE, user.getUserId(), vo.getLblKCode());
		if (editor != null) {
			addErrMessage(MospUtility.getMessage(msg, PayrollConst.MSG_EXCLUSIVE, editor));
		}
		setNeedExclusive(true);
	}

	/**
	 * データ挿入
	 * @param vo       対象VO
	 * @param isInsert 挿入フラグ
	 * @throws Exception
	 */
	public void regist(HumanCalcVo vo, boolean isInsert) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// パラメータの妥当性確認
		vo.validate();
		// 人事基本情報取得
		getSelectedEmployeeBasis(vo);
		// 人事給与情報取得
		findHumanCalcInfo(vo.getLblKCode(), true);
		// 存在確認
		if (isInsert) {
			//chkDuplicate(umBasisDao.findForKey(uhBasisDto.getKCode()), vo);
		}
		// DTO準備
		
		CmSocInsuranceDto            upCmSocInsuranceDto = new CmSocInsuranceDto           ();
		CmResidenceTaxDto            upCmResidenceTaxDto = new CmResidenceTaxDto           (); 
		CmIncomeTaxDto               upCmIncomeTaxDto    = new CmIncomeTaxDto              ();
		CmMidwayEnterDto			 upCmMidwayEnterDto  = new CmMidwayEnterDto				();
		
		ArrayList<CmPaymentMeansDto> listUpPaymentMeans  = new ArrayList<CmPaymentMeansDto>();
		ArrayList<CmCommutationDto > listUpCommutation   = new ArrayList<CmCommutationDto >();
		ArrayList<CmUnitAmountDto  > listUpUnitAmount    = new ArrayList<CmUnitAmountDto  >();

		vo.setDtoFields(
				upCmSocInsuranceDto,
				upCmResidenceTaxDto, 
				upCmIncomeTaxDto   ,
				upCmMidwayEnterDto,
				listUpPaymentMeans ,
				listUpCommutation  ,
				listUpUnitAmount
		);
		// 計算月確認
		/*
		if (!isAfterCalc(vo.getExpectedDate())) {
			String errMessage = MospUtility.getMessage(msg, UnicConst.MSG_APPLY_BEFORE_CALC, "");
			addErrMessage(errMessage);
			throw new MospException(UnicConst.EX_APPLY_BEFORE_CALC, errMessage);
		}
		*/
		// データ更新
		// 健康保険
		if (cmSocInsuranceDao.findForKey(
				upCmSocInsuranceDto.getKCode(), upCmSocInsuranceDto.getInsExpectedDate()) == null
		) {
			cmSocInsuranceDao.insert(upCmSocInsuranceDto);
		} else {
			// 登録内容チェック
			if (vo.checkInsuranceDtoFields(cmSocInsuranceDto, upCmSocInsuranceDto)) {
				// 排他処理
				cmSocInsuranceDao.findForUpdate(upCmSocInsuranceDto.getKCode());
				// 更新処理
				cmSocInsuranceDao.update(upCmSocInsuranceDto);
				
			}
		}
		// 住民税
		if (cmResidenceTaxDao.findForKey(
				upCmResidenceTaxDto.getKCode(), upCmResidenceTaxDto.getResExpectedDate()) == null
		) {
			cmResidenceTaxDao.insert(upCmResidenceTaxDto);
		} else {
			// 登録内容チェック
			if (vo.checkResidenceTaxDtoFields(cmResidenceTaxDto, upCmResidenceTaxDto)) {
				// 排他処理
				cmResidenceTaxDao.findForUpdate(upCmResidenceTaxDto.getKCode());
				// 更新処理
				cmResidenceTaxDao.update(upCmResidenceTaxDto);
			}
		}
		// 所得税
		if (cmIncomeTaxDao.findForKey(
				upCmIncomeTaxDto.getKCode(), upCmIncomeTaxDto.getIncExpectedDate()) == null
		) {
			cmIncomeTaxDao.insert(upCmIncomeTaxDto);
		} else {
			// 登録内容チェック
			if (vo.checkIncomeTaxDtoFields(cmIncomeTaxDto, upCmIncomeTaxDto)) {
				// 排他処理
				cmIncomeTaxDao.findForUpdate(upCmIncomeTaxDto.getKCode());
				// 更新処理
				cmIncomeTaxDao.update(upCmIncomeTaxDto);
			}
		}
		// 登録内容チェック
		if (vo.checkPaymentMeansDtoFields(listPaymentMeans, listUpPaymentMeans)) {
			// 支給方法
			// フリガナ、名義が社員名と同じでかつ、その他が空のデータは登録させない。
			listUpPaymentMeans = vo.chkRegistPaymentData(listUpPaymentMeans);
			// 既存支給方法削除
			cmPaymentMeansDao.deleteForEmployee(vo.getLblKCode());
			for (Iterator<CmPaymentMeansDto> it = listUpPaymentMeans.iterator(); it.hasNext();) {
				CmPaymentMeansDto cmPaymentMeansDto = it.next();
				cmPaymentMeansDao.insert(cmPaymentMeansDto);
			}
			
		}
		// 登録内容チェック
		if (vo.checkCommutationDtoFields(listCommutation, listUpCommutation)) {
			// 通勤手当
			cmCommutationDao.deleteForEmployee(vo.getLblKCode());
			for (Iterator<CmCommutationDto> it = listUpCommutation.iterator(); it.hasNext();) {
				CmCommutationDto cmCommutationDto = it.next();
				cmCommutationDao.insert(cmCommutationDto);
			}
			
		}
		// 登録内容チェック
		if (vo.checkUnitAmountDtoFields(listUnitAmount, listUpUnitAmount)) {
			// 計算単価
			cmUnitAmountDao.deleteForEmployee(vo.getLblKCode());
			for (Iterator<CmUnitAmountDto> it = listUpUnitAmount.iterator(); it.hasNext();) {
				CmUnitAmountDto cmUnitAmountDto = it.next();
				cmUnitAmountDao.insert(cmUnitAmountDto);
			}
		}

		// 中途入社
		if ( cmMidwayEnterDao.findForKey(
				upCmMidwayEnterDto.getKCode() ) == null
		) {
			cmMidwayEnterDao.insert(upCmMidwayEnterDto);
		} else {
			// 登録内容チェック
			if (vo.checkCmMidwayEnterDtoFields(cmMidwayEnterDto, upCmMidwayEnterDto)) {
				// 更新処理
				cmMidwayEnterDao.update(upCmMidwayEnterDto);
			}
		}
		
		// DTO再取得
		findHumanCalcInfo(vo.getLblKCode(), false);

		// コミット
		commit();
		// モード設定
		vo.setMode(HumanCalcVo.MODE_UPDATE);
		// メッセージ設定
		vo.setMessage(MospUtility.getMessage(msg, MospConst.MSG_INSERT, ""));
	}
	
	/**
	 * 口座名、フリガナ取得
	 * @param vo　対象VO
	 */
	protected void getHolderName(HumanCalcVo vo) {
		// 設定準備
		ArrayList<CmPaymentMeansDto> listAddPaymentMeans = new ArrayList<CmPaymentMeansDto>();
		for (int i = 0; i < PayrollConst.PAYMENT_MEANS_COUNT; i++) {
			// 支給方法リストが存在しない場合
			if (listPaymentMeans.size() == 0) {
				// DTOを初期化
				CmPaymentMeansDto cmPaymentMeansDto = setPaymentMeansData(vo, i);
				// リストに追加
				listAddPaymentMeans.add(cmPaymentMeansDto);
				continue;
			}
			// 取得したリスト
			for (int j = 0; j < listPaymentMeans.size(); j++) {
				CmPaymentMeansDto cmPaymentMeansDto = listPaymentMeans.get(j);
				// 連番と一致したらADDリストに設定
				if (i == cmPaymentMeansDto.getMeansSequence()) {
					// リストに追加
					listAddPaymentMeans.add(cmPaymentMeansDto);
					break;
				}
				// 最後まで一致しない場合は名義を追加したDTOを設定
				if (j == listPaymentMeans.size() - 1) {
					// DTOを初期化
					cmPaymentMeansDto = setPaymentMeansData(vo, i);
					// リストに追加
					listAddPaymentMeans.add(cmPaymentMeansDto);
				}
			}
		}
		// 設定を反映
		listPaymentMeans = listAddPaymentMeans;
	}
	
	/**
	 * 支給方法設定
	 * @param vo　対象VO
	 * @param idx　連番
	 * @return
	 */
	protected CmPaymentMeansDto setPaymentMeansData(HumanCalcVo vo,int idx) {
		// DTOを初期化
		CmPaymentMeansDto cmPaymentMeansDto = new CmPaymentMeansDto();
		cmPaymentMeansDto.setKCode(vo.getLblKCode());
		cmPaymentMeansDto.setMeansSequence(idx);
		cmPaymentMeansDto.setHolderName(vo.getEscLblKName());
		cmPaymentMeansDto.setHolderKana(vo.getEscLblKKana());
		cmPaymentMeansDto.setPaidBankCode  ("");
		cmPaymentMeansDto.setPaidBranchCode("");
		return cmPaymentMeansDto;
	}
	
	private void setFinanceName( HumanCalcVo vo)
	throws SQLException, IllegalAccessException, NoSuchFieldException
{
	if (listPaymentMeans.size() == 0) {
		return;
	}
	// DAOの準備
	CmBankDao cmBankDao = new CmBankDao();
	cmBankDao.initDao(cfg, cmd, aspUser, user, conn);
	// DAOの準備
	CmBranchDao cmBranchDao = new CmBranchDao();
	cmBranchDao.initDao(cfg, cmd, aspUser, user, conn);
	vo.lblPaidBankName = new String[listPaymentMeans.size()];
	vo.lblPaidBranchName = new String[listPaymentMeans.size()];
	for (int i = 0; i < listPaymentMeans.size(); i++) {
		CmPaymentMeansDto cmPaymentMeansDto = listPaymentMeans.get(i); 
		CmBankDto cmBankDto = cmBankDao.findForKey(cmPaymentMeansDto.getPaidBankCode());
		if (cmBankDto != null) {
			vo.lblPaidBankName[i] = cmBankDto.getBankName();
		} else {
			vo.lblPaidBankName[i] = cmPaymentMeansDto.getPaidBankCode();
		}
		CmBranchDto cmBranchDto = cmBranchDao.findForKey(cmPaymentMeansDto.getPaidBankCode(), cmPaymentMeansDto.getPaidBranchCode());
		if (cmBranchDto != null) {
			vo.lblPaidBranchName[i] = cmBranchDto.getBranchName();
		} else {
			vo.lblPaidBranchName[i] = cmPaymentMeansDto.getPaidBranchCode();
		}
		
	}
	
	
}
	


}
