/********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：請求書送付先変更コンポーネント部品クラス
 *  ソースファイル名：JKKSeikyuSendAdchgCC.java
 *  作成者          ：FJ
 *  日付            ：2012年8月28日
 *＜機能概要＞
 *  住所変更に伴う請求書の
 *  送付先の変更を行う部品クラス。
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v1.00.00    2012/08/28  FJ          新規作成
 *  v8.00.00    2014/04/03  FJ)星野     OM-2014-0001265対応
 ********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKAdchgConstCC;
import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.sun.enterprise.tools.common.util.StringUtils;

import eo.ejb.cbs.cbsmsg.EKK0491A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0491C060CBSMsg;

/**
 * 請求書送付先変更コンポーネント部品クラス.
 * <br>
 * @author FJ
 */
public class JKKSeikyuSendAdchgCC extends AbstractCommonComponent {

	/** セッションハンドル保持域 */
	private static ThreadLocal<SessionHandle> keepSesHandle = new ThreadLocal<SessionHandle>()
	{
		// 保持域への設定はinitialValue()ではなくset()を使用する為、
		// initialValue()は実装しない
	};

	/**
	 * コンストラクタ.
	 * <br>
	 */
	public JKKSeikyuSendAdchgCC() {
	}
	
	/** 住所項目_移転先（paramMap） */
	private static final String[] AD_ITNS = {
		// 移転先_都道府県
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_STATE,
		// 移転先_市区町村
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_CITY,
		// 移転先_大字通称名
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_OAZTSU,
		// 移転先_字丁目
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_AZCHO,
		// 移転先_番地・号
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_BNCHIGO,
		// 移転先_建物名
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_ADRTTM,
		// 移転先_部屋番号
		JKKAdchgConstCC.PARAM_KEY_ITENS_AD_ADRRM,
	};
	
	/** 住所項目_請求所送付先（EKK0491A010CBSMsg1List） */
	private static final String[] AD_SOHUS = {
		// 送付先_都道府県名
		EKK0491A010CBSMsg1List.SOHUS_STATE_NM,
		// 送付先_市区町村名
		EKK0491A010CBSMsg1List.SOHUS_CITY_NM,
		// 送付先_大字通称名
		EKK0491A010CBSMsg1List.SOHUS_OAZTSU_NM,
		// 送付先_字丁目名
		EKK0491A010CBSMsg1List.SOHUS_AZCHO_NM,
		// 送付先_番地・号
		EKK0491A010CBSMsg1List.SOHUS_BNCHIGO,
		// 送付先_建物名
		EKK0491A010CBSMsg1List.SOHUS_ADRTTM,
		// 送付先_部屋番号
		EKK0491A010CBSMsg1List.SOHUS_ADRRM,
	};
	
	/** 住所項目_契約者 */
	private static final String[] AD_KMK_KSH = {
		"keisha_state_nm",
		"keisha_city_nm",
		"keisha_oaztsu_nm",
		"keisha_azcho_nm",
		"keisha_bnchigo",
		"keisha_adrttm",
		"keisha_adrrm"
	};

	/**
	 * 請求書送付先変更
	 * <br>
	 * @param   handle     セッションマネージャなどを持ったハンドル情報
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Throwable  例外が発生した場合
	 * @return  リクエストパラメータ(param)に戻り値を追加して返却する
	 */
	public IRequestParameterReadWrite seikyuSendAdchg(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable {

		try {

			/** 事前準備 */
			HashMap<String, String> condMap;
			HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
			HashMap<String, Object> reqMap;
			Map<?, ?> resMap;

			/** リソース保持 */
			// セッションハンドルをローカル変数に保持
			keepSesHandle.set(handle);
			
			// 住所変更登録コモンコンポーネントマッピングクラスインスタンスを取得
			JKKAdchgMapperCC mapper = JKKAdchgMapperCC.getInstance();

			// SCリクエストInvokerを取得
			ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();


			/** パラメータからの展開 */
			// param.請求書送付先住所変更対象リスト を抽出
			ArrayList<HashMap<String, Object>> seiky_shs_list = (ArrayList<HashMap<String, Object>>)paramMap.get(JKKAdchgConstCC.PARAM_KEY_SEIKY_SHS_CHG_TGT_LIST);

			/** 請求書送付先住所変更ループ */
			Iterator<HashMap<String, Object>> seiky_shs_list_ite = seiky_shs_list.iterator();
			while(seiky_shs_list_ite.hasNext()) {

				HashMap<String, Object> cur_seiky_shs = seiky_shs_list_ite.next();

				// ・EKK0491A010  請求契約一意照会
				condMap = new HashMap<String, String>();
				condMap.put(JKKAdchgMapperCC.COND_KEY_SEIKY_KEI_NO, (String)cur_seiky_shs.get(JKKAdchgConstCC.PARAM_KEY_SEIKY_SHS_CHG_SEIKY_KEI_NO));
// OM-2014-0001265対応 20140403 星野 MOD START
//				condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_OPE_DATE));
				condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_CHG_RSV_YMD));
// OM-2014-0001265対応 20140403 星野 MOD END
				reqMap = mapper.setEKK0491A010( param, fixedText, condMap);
				resMap = scCall.run(reqMap, keepSesHandle.get());
				HashMap<String, Object> kk0491_a010_map = mapper.getEKK0491A010(param, fixedText, resMap);
				mapper.scResultCheck(param);


				// kk0491_a010_map.送付先住所コードをparam.移転先_住所コードに差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_AD_CD, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_CD));
				// kk0491_a010_map.送付先郵便番号をparam.移転先_郵便番号に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_PCD, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_POST_CD));
				// kk0491_a010_map.送付先都道府県名をparam.移転先_都道府県に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_STATE_NM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_STATE));
				// kk0491_a010_map.送付先市区町村名をparam.移転先_市区町村に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_CITY_NM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_CITY));
				// kk0491_a010_map.送付先大字通称名をparam.移転先_大字通称名に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_OAZTSU_NM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_OAZTSU));
				// kk0491_a010_map.送付先字丁目名をparam.移転先_字丁目に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_AZCHO_NM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_AZCHO));
				// kk0491_a010_map.送付先住所補記・建物名をparam.移転先_番地・号に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_BNCHIGO, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_BNCHIGO));
				// kk0491_a010_map.送付先住所補記・部屋番号をparam.移転先_建物名に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_ADRTTM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_ADRTTM));
				// kk0491_a010_map.送付先番地号をparam.移転先_部屋番号に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_ADRRM, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_AD_ADRRM));
				// kk0491_a010_map.送付先電話番号をparam.移転先_電話番号に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SOHUS_TELNO, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_ITENS_TLN));
				// kk0491_a010_map.予約適用開始予定年月日をparam.変更予定年月日に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.RSV_TSTA_KIBO_YMD, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_CHG_RSV_YMD));
				// kk0491_a010_map.異動区分をparam.異動区分に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.IDO_DIV, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_IDO_DIV));
				// kk0491_a010_map.申込明細番号をparam.申込明細番号に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.MSKM_DTL_NO, paramMap.get(JKKAdchgConstCC.PARAM_KEY_MSKM_DTL_NO).toString());
				// kk0491_a010_map.予約適用年月日をparam.変更予定年月日に差替
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.RSV_APLY_YMD, paramMap.get(JKKAdchgConstCC.PARAM_KEY_CHG_RSV_YMD).toString());

				// kk0491_a010_mapへ請求書送付先_契約者住所差異フラグを設定
				kk0491_a010_map.put(EKK0491A010CBSMsg1List.SKS_SHS_KSH_AD_SAI_FLG,  getAdchgSksShsChgUm(param, paramMap, kk0491_a010_map, fixedText));

				// kk0491_a010_mapへ更新年月日時分秒(更新前)を設定
				String befUpdDtm = (String)cur_seiky_shs.get(JKKAdchgConstCC.PARAM_KEY_SEIKY_SHS_CHG_UPD_DTM_BEF);
				String aftUpdDtm = (String)cur_seiky_shs.get(JKKAdchgConstCC.PARAM_KEY_SEIKY_SHS_CHG_UPD_DTM_AFT);
				kk0491_a010_map.put(JKKAdchgMapperCC.UPD_DT_SEIKY_KEI_UPD_DTM_BEF, getUpdDtmBef(befUpdDtm, aftUpdDtm));


				// ・EKK0491C060  請求契約内容変更
				reqMap = mapper.setEKK0491C060(param, fixedText, kk0491_a010_map);
				resMap = scCall.run(reqMap, keepSesHandle.get());
				HashMap<String, Object> kk0491_c060_map = mapper.getEKK0491C060(param, fixedText, resMap);
				mapper.scResultCheck(param);


				// 更新後の更新年月日時分秒をparamへ設定
				cur_seiky_shs.put(JKKAdchgConstCC.PARAM_KEY_SEIKY_SHS_CHG_UPD_DTM_AFT, (String)kk0491_c060_map.get(EKK0491C060CBSMsg.UPD_DTM));
			}


			} finally {
				
			// ・セッションハンドル保持域
			if(keepSesHandle.get() != null) {
				keepSesHandle.remove();
			}
		}

		return param;
	}
	
	/**
	 * <p>
	 * 請求書送付先_契約者住所差異フラグを取得します.
	 * </p>
	 * <li>請求書送付先チェックがない場合　⇒　現在の請求書送付先住所<br> 
	 * <li>請求書送付先チェックがある場合　⇒　移転先住所<br>
	 * とし、契約者住所と比較し、差異がある場合 "1" ない場合 "0" を返却します。
	 * 
	 * @param umu 有無
	 * @return "1"(有り)の場合、true / 左記以外の場合　false
	 * @throws Throwable 
	 */
	private Object getAdchgSksShsChgUm(IRequestParameterReadWrite param,
																	HashMap<String, Object> paramMap,
																	HashMap<String, Object> kk0491_a010_map,
																	String fixedText) throws Throwable {

		// 請求書送付先変更有無
		String adchgSksShsChgUm = "";

		// 請求書送付先変更があるかどうか判定
		if (isUmuAri((String) paramMap.get(JKKAdchgConstCC.PARAM_KEY_ADCHG_SKS_SHS_CHG_UM))) {
			// 請求書送付先変更有りの場合、移転先住所を元に契約者住所差異判定を行なう
			adchgSksShsChgUm = checkKshAd(param, paramMap, AD_ITNS, fixedText);
		} else {
			// 請求書送付先変更なしの場合、現在の請求書送付先住所を元に契約者住所差異判定を行なう
			adchgSksShsChgUm = checkKshAd(param, kk0491_a010_map, AD_SOHUS, fixedText);
		}
		return adchgSksShsChgUm;
	}
	
	/**
	 * <p>
	 * 有無が"有"かどうか判定します.
	 * </p>
	 * <li>"0"の場合無し<br> <li>"1"の場合有り<br>
	 * 
	 * @param umu
	 *            有無
	 * @return "1"(有り)の場合、true / 左記以外の場合　false
	 */
	private boolean isUmuAri(String umu) {

		boolean ari = false;

		if ("1".equals(umu)) {
			ari = true;
		}
		return ari;
	}
	
	/**
	 * 契約者住所差異判定.
	 * <br>
	 * @param  param     パラメータリクエスト
	 * @param  jadgmentMap  判定情報が格納されているマップ
	 * @param  checkList 判定項目が格納されているマップ
	 * @return "0"(差異なし)、"1"(差異あり)、""(判定失敗)
	 * @throws Throwable 
	 */
	private String checkKshAd(IRequestParameterReadWrite param, HashMap<String, Object> jadgmentMap, String[] checkList, String fixedText)throws Throwable {
		try {
			
			/** 事前準備 */
			HashMap<String, String> condMap;
			HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
			HashMap<String, Object> reqMap;
			Map<?, ?> resMap;
			
			// 住所変更登録コモンコンポーネントマッピングクラスインスタンスを取得
			JKKAdchgMapperCC mapper = JKKAdchgMapperCC.getInstance();

			// SCリクエストInvokerを取得
			ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
			
			if (jadgmentMap == null) {
				return "";
			}
			
			// ・ECK0011A010  お客様一意照会
			condMap = new HashMap<String, String>();
			condMap.put( JKKAdchgMapperCC.COND_KEY_SYSID, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_SYSID));
			condMap.put( JKKAdchgMapperCC.COND_KEY_OPEDATE, (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_OPE_DATE));
			reqMap = mapper.setECK0011A010(param, fixedText, condMap);
			resMap = scCall.run( reqMap, keepSesHandle.get() );
			HashMap<String, Object> ck0011_a010_map = mapper.getECK0011A010( param, fixedText, resMap );
			mapper.scResultCheck(param);

			if (ck0011_a010_map == null) {
				throw new RequestParameterException();
			}

			for (int i = 0; i < AD_KMK_KSH.length; i ++) {
				if (getMapString(ck0011_a010_map, AD_KMK_KSH[i]).equals(getMapString(jadgmentMap, checkList[i]))) {
					return "1";
				}
			}
		} catch (RequestParameterException e) {
			return "";
		}
		return "0";
	}
	
	/**
	 * パラメータ取得(HashMap).
	 * <br>
	 * @param  targetMap  取得元マップ
	 * @param  targetKey  取得元キー項目
	 * @return 取得文字列
	 */
	private String getMapString(HashMap<String, Object> targetMap, String targetKey) {
		String resultStr = new String();

		if (targetMap != null) {
			if ((targetKey != null) && (!"".equals(targetKey))) {
				if (targetMap.containsKey(targetKey)) {
					resultStr = (String) targetMap.get(targetKey);
				}
			}
		}

		return resultStr;
	}
	
	/**
	 * 更新前更新年月日 取得処理.
	 * <dd>以下の振る舞いで更新前更新年月日を呼び元へ返却する.
	 * <dd><dd>
	 * <table border="1">
	 * <th>条件</th><th>返却値</th>
	 * <tr><td>比較元更新年月日＝Empty</td><td>比較先更新年月日</td></tr>
	 * <tr><td>比較先更新年月日＝Empty</td><td>比較元更新年月日</td></tr>
	 * <tr><td>比較元更新年月日＞比較先更新年月日</td><td>比較元更新年月日</td></tr>
	 * <tr><td>比較元更新年月日≦比較先更新年月日</td><td>比較先更新年月日</td></tr>
	 * </table>
	 * @param   srcUpdDtm  比較元更新年月日
	 * @param   dstUpdDtm  比較先更新年月日
	 * @throws  Exception  例外が発生した場合
	 * @return  更新前更新年月日
	 */
	public String getUpdDtmBef(String srcUpdDtm, String dstUpdDtm) throws Exception {

		/** 比較元更新年月日 Emptyチェック */
		if (StringUtils.isEmpty(srcUpdDtm)) {
			return dstUpdDtm;
		}

		/** 比較先更新年月日 Emptyチェック */
		if (StringUtils.isEmpty(dstUpdDtm)) {
			return srcUpdDtm;
		}


		/** 比較元更新年月日＞比較先更新年月日 判定 */
		if (srcUpdDtm.compareTo(dstUpdDtm) > 0) {
			return srcUpdDtm;

		} else {

			return dstUpdDtm;

		}
	}

}