/********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：住所変更情報登録コンポーネント部品クラス
 *  ソースファイル名：JKKAdchgAddCmnCC.java
 *  作成者          ：FJ
 *  日付            ：2011年11月10日
 *＜機能概要＞
 *  住所変更に伴う住所変更情報の登録処理を行う部品クラス。
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v1.00.00    2011/11/10  FJ          新規作成
 *  v3.00.00    2012/04/28  FJ          巻取り@対応
 *
 ********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.IRequestParameterReadOnly;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANMsg;

import eo.common.constant.JKKStrConst;
import eo.ejb.cbs.cbsmsg.EKK0241A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0241A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0241C010CBSMsg;

/**
 * 住所変更サービス契約回線内訳変更部品クラス.
 * <br>
 * @author FJ
 */
public class JKKAdchgModifyKaisenTgSvkeiCC extends AbstractCommonComponent {

	/** セッションハンドル保持域 */
	private static ThreadLocal<SessionHandle> keepSesHandle = new ThreadLocal<SessionHandle>()
	{
		// 保持域への設定はinitialValue()ではなくset()を使用する為、
		// initialValue()は実装しない
	};
	
	/** 引継領域 */
	//private static ThreadLocal<HashMap<String, Object>> ccMap = new ThreadLocal<HashMap<String,Object>>();
	HashMap<String, Object> paramMap = new HashMap<String, Object>();
	
	/** マッパー */
	private static JKKAdchgModifyKaisenTgSvkeiCCMapper mapper = new JKKAdchgModifyKaisenTgSvkeiCCMapper();
	
	/** 引継情報 */
	private class MAP_KEY {
		/** 払出サービス契約番号マップリスト */
		private static final String NEW_SVC_KEI_NO_LIST = "new_svc_kei_no_list";
		/** サービス契約回線内訳番号 */
		private static final String SVC_KEI_KAISEN_UCWK_NO = "svc_kei_kaisen_ucwk_no";
		/** 機能コード */
		private static final String FUNC_CODE = "func_code";
		/** 非更新対象サービス契約番号リスト */
		private static final String IGNORE_SVC_KEI_NO_LIST = "ingore_svc_kei_no_list";
	}
	
	/** 作業領域 */
	private class WORK {
		/** 最終更新年月日時分秒 */
		private static final String LAST_UPD_DTM = "last_upd_dtm";
	}
	
	/**
	 * コンストラクタ.
	 * <br>
	 */
	public JKKAdchgModifyKaisenTgSvkeiCC() {
	}

	/**
	 * 回線対象サービス契約の使用開始日付を運用日に変更する。
	 * <br>
	 * @param   handle
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Exception  例外が発生した場合
	 */
	public IRequestParameterReadWrite modStaYmdToUnyoDate( SessionHandle handle, IRequestParameterReadWrite param, String fixedText ) throws Throwable, Exception
	{
		// 引継情報をクラス変数に代入する
		if (!init(param, fixedText)) {
			return param;
		}
		
		// 引継情報の払出サービス契約番号マップリストを取得し、ループ対象とする
		List<HashMap<String, Object>> newSvcKeiNoList =
			(List<HashMap<String, Object>>)paramMap.get(MAP_KEY.NEW_SVC_KEI_NO_LIST);
		if (newSvcKeiNoList == null) {
			newSvcKeiNoList = new ArrayList<HashMap<String,Object>>();
		}
		// 元情報への更新対象外のサービス契約番号（modStaYmdToMaxDate()で更新しない対象サービス契約）
		ArrayList<HashMap<String, Object>> ignoreSvcKeiNoList = new ArrayList<HashMap<String, Object>>();
		
		for (HashMap<String, Object> newSvcKeiNoMap : newSvcKeiNoList) {
			//-------------------------------------------
			// 回線対象サービス契約一意照会
			//-------------------------------------------
			executeEKK0241A010(handle, param, newSvcKeiNoMap);
			
			// 更新対象は適用開始年月日が最大値(20991231)のレコードのみ
			if (JKKStrConst.END_YMD_DEFAULT.equals(getStringKk0241A010(param, EKK0241A010CBSMsg1List.KAISEN_UCWK_USE_STAYMD))) {
				//-------------------------------------------
				// 回線対象サービス契約変更
				//-------------------------------------------
				executeEKK0241C010(handle, param, (String)paramMap.get("iplYmd"));
			} else {
				// 適用開始年月日を元に戻す際に対象とならないようignoreListに登録しておく
				ignoreSvcKeiNoList.add(newSvcKeiNoMap);
			}
		}
		
		HashMap<String, Object> repairMap = (HashMap<String, Object>)param.getData((String)paramMap.get("repair_cc_no"));
		repairMap.put(MAP_KEY.IGNORE_SVC_KEI_NO_LIST, ignoreSvcKeiNoList);
		
		return param;
	}

	/**
	 * 回線対象サービス契約の使用開始日付を最大日付(20991231)に変更する。
	 * <br>
	 * @param   handle
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Exception  例外が発生した場合
	 */
	public IRequestParameterReadWrite modStaYmdToMaxDate( SessionHandle handle, IRequestParameterReadWrite param, String fixedText ) throws Throwable, Exception
	{
		// 引継情報をクラス変数に代入する
		if (!init(param, fixedText)) {
			return param;
		}
		
		// 引継情報の払出サービス契約番号マップリストを取得し、ループ対象とする
		List<HashMap<String, Object>> newSvcKeiNoList =
			(List<HashMap<String, Object>>)paramMap.get(MAP_KEY.NEW_SVC_KEI_NO_LIST);
		if (newSvcKeiNoList == null) {
			newSvcKeiNoList = new ArrayList<HashMap<String,Object>>();
		}
		
		for (HashMap<String, Object> newSvcKeiNoMap : newSvcKeiNoList) {
			// 更新対象外情報(ignoreSvcKeiNoList)に無いサービス契約であることを確認して更新を行う
			if (hasToBeProcessed(param, (String)newSvcKeiNoMap.get("svc_kei_no"))) {
				//-------------------------------------------
				// 回線対象サービス契約一意照会
				//-------------------------------------------
				executeEKK0241A010(handle, param, newSvcKeiNoMap);
			
				//-------------------------------------------
				// 回線対象サービス契約変更
				//-------------------------------------------
				executeEKK0241C010(handle, param, JKKStrConst.END_YMD_DEFAULT);
			}
		}
		return param;
	}
	
	/**
	 * マップデータをローカル領域に保存
	 * 
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	private boolean init(IRequestParameterReadWrite param, String fixedText) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		if (paramMap == null) {
			return false;
		}
		this.paramMap = (HashMap<String, Object>)param.getData(fixedText);
		return true;
	}
	
	/**
	 * 処理対象か検査
	 * 
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	private boolean hasToBeProcessed(IRequestParameterReadWrite param, String svc_kei_no) throws RequestParameterException
	{
		// 更新対象外のサービス契約番号（modStaYmdToUnyoDate()で更新されなかった対象サービス契約）
		ArrayList<HashMap<String, Object>> ignoreSvcKeiNoList = (ArrayList<HashMap<String, Object>>)paramMap.get(MAP_KEY.IGNORE_SVC_KEI_NO_LIST);
		if (ignoreSvcKeiNoList == null) {
			return true;
		}
		for (HashMap<String, Object> ignoreSvcKeiNoMap : ignoreSvcKeiNoList) {
			String ignoreSvcKeiNo = (String)ignoreSvcKeiNoMap.get("svc_kei_no");
			if (ignoreSvcKeiNo != null
					&& ignoreSvcKeiNo.equals(svc_kei_no)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 回線対象サービス契約一意照会サービスI/F実行
	 * 
	 * @param handle
	 * @param param
	 * @param newSvcKeiNoMap
	 * @return
	 * @throws Throwable 
	 */
	private void executeEKK0241A010(	SessionHandle handle,
										IRequestParameterReadWrite param,
										HashMap<String, Object> newSvcKeiNoMap) throws Throwable
	{
		HashMap<String, Object> inMap = new HashMap<String, Object>();
		param.setData(JKKKaisenUseStartUpdateCCMapper.TEMPLATE_ID_EKK0241A010, inMap);
		
		// 機能コード（固定：1）
		inMap.put(EKK0241A010CBSMsg.FUNC_CODE, "1");
		// 引継データ.サービス契約番号 → ＫＥＹ＿サービス契約番号
		inMap.put(EKK0241A010CBSMsg.KEY_SVC_KEI_NO, newSvcKeiNoMap.get("svc_kei_no"));
		// 引継データ.サービス契約回線内訳番号 → ＫＥＹ＿サービス契約回線内訳番号
		inMap.put(EKK0241A010CBSMsg.KEY_SVC_KEI_KAISEN_UCWK_NO, paramMap.get(MAP_KEY.SVC_KEI_KAISEN_UCWK_NO));
		
		/* ◇上りマッピング処理 */
		HashMap<String, Object> paramMap = mapper.editInMsgEKK0241A010(param);
		/* ◇ＳＣ呼出実行 */
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		Map<?, ?> result = scCall.run(paramMap, handle);
		/* ◇下りマッピング処理 */
		param = mapper.editResultRPEKK0241A010(result, param);
		checkExecutionResult(result);
		
		// 最終更新年月日
		//getWorkMap(param).put(WORK.LAST_UPD_DTM, getStringKk0241A010(param, EKK0241A010CBSMsg1List.LAST_UPD_DTM));
		
		return;
	}
	
	/**
	 * 回線対象サービス契約変更サービスI/F実行
	 * 
	 * @param handle
	 * @param param
	 * @return
	 * @throws Throwable 
	 */
	private void executeEKK0241C010(	SessionHandle handle,
										IRequestParameterReadWrite param, String userStaYmd) throws Throwable
	{
		HashMap<String, Object> inMap = new HashMap<String, Object>();
		param.setData(JKKKaisenUseStartUpdateCCMapper.TEMPLATE_ID_EKK0241C010, inMap);
		
		// 引継データ.機能コード → 機能コード
		inMap.put(EKK0241C010CBSMsg.FUNC_CODE, (String)paramMap.get(MAP_KEY.FUNC_CODE));
		// 回線対象サービス契約一意照会.サービス契約番号 → サービス契約番号
		inMap.put(EKK0241C010CBSMsg.SVC_KEI_NO, getStringKk0241A010(param, EKK0241A010CBSMsg1List.SVC_KEI_NO));
		// 回線対象サービス契約一意照会.サービス契約回線内訳番号 → サービス契約回線内訳番号
		inMap.put(EKK0241C010CBSMsg.SVC_KEI_KAISEN_UCWK_NO, getStringKk0241A010(param, EKK0241A010CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO));
		// userStaYmd → 回線内訳使用開始年月日
		inMap.put(EKK0241C010CBSMsg.KAISEN_UCWK_USE_STAYMD, userStaYmd);
		// 回線対象サービス契約一意照会.回線内訳使用終了年月日 → 回線内訳使用終了年月日
		inMap.put(EKK0241C010CBSMsg.KAISEN_UCWK_USE_ENDYMD, getStringKk0241A010(param, EKK0241A010CBSMsg1List.KAISEN_UCWK_USE_ENDYMD));
		// 最終更新年月日
		inMap.put(EKK0241C010CBSMsg.UPD_DTM_BF, getStringKk0241A010(param, EKK0241A010CBSMsg1List.LAST_UPD_DTM));
		
		/* ◇上りマッピング処理 */
		HashMap<String, Object> paramMap = mapper.editInMsgEKK0241C010(param);
		/* ◇ＳＣ呼出実行 */
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		Map<?, ?> result = scCall.run(paramMap, handle);
		/* ◇下りマッピング処理 */
		param = mapper.editResultRPEKK0241C010(result, param);
		checkExecutionResult(result);
		
		return;
	}
	
	/**
	 * 回線対象サービス契約一意照会の結果取得
	 * 
	 * @param param
	 * @param target
	 * @return
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private String getStringKk0241A010(IRequestParameterReadOnly param, String target) throws RequestParameterException
	{
		// 回線対象サービス契約一意照会の結果取得
		HashMap<String, Object> ekk0241A010Map = (HashMap<String, Object>)param.getData(JKKKaisenUseStartUpdateCCMapper.TEMPLATE_ID_EKK0241A010);
		ArrayList ekk0241A010MapList = (ArrayList)ekk0241A010Map.get(EKK0241A010CBSMsg.EKK0241A010CBSMSG1LIST);
		ekk0241A010Map = (HashMap<String, Object>)ekk0241A010MapList.get(0);
		
		return (String)ekk0241A010Map.get(target);
	}
	
	/**
	 * 呼び出したサービスIFの処理結果を判定します。
	 * 
	 * @param result
	 * @throws Throwable
	 */
	private void checkExecutionResult(Map<?, ?> result) throws Throwable
	{
		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		Integer status = templates[0].getInt(JCMConstants.STATUS_INT_KEY);
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if (!("0".equals(rtnCode) && 0 == status.intValue()))
		{
			SCCallException scCallEx = new SCCallException("戻り値不正", rtnCode, status);
			throw scCallEx;
		}
	}
	
	/**
	 * 作業領域取得
	 * 
	 * @param param
	 * @return
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private HashMap<String, Object> getWorkMap(IRequestParameterReadWrite param) throws RequestParameterException
	{
		Map workAreaMap = (Map)param.getMappingWorkArea();
		if (workAreaMap == null) {
			workAreaMap = new HashMap();
			param.setMappingWorkArea(workAreaMap);
		}
		HashMap<String, Object> workMap = (HashMap<String, Object>)workAreaMap.get("WORK");
		if (workMap == null) {
			workMap = new HashMap<String, Object>();
			workAreaMap.put("WORK", workMap);
		}
		return workMap;
	}
}
