/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKKKTKSvcRsvIcrnOpsCC
*	ソースファイル名：JKKKKTKSvcRsvIcrnOpsCC.java
*	作成者			：FJ
*	日付			：2021年05月21日
*＜機能概要＞
*	機器提供サービス契約予約一覧照会（オペレータ支援）CC
*	JKKKktkSvcKeiRrkListCC.java をベースに流用新規作成
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   v53.00.00   2021/05/21  FJ)星野     【ANK-4030-00-00】オペレータ支援向けAPI機能変更（2021年6月）
*   v53.00.01   2021/06/11  FJ)星野     【ANK-4030-01-00】交換取消レコードは返却しない
**********************************************************************/
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.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.CCException;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.model.common.check.HalfCharCheck;
import com.fujitsu.futurity.model.common.check.LengthCheck;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JKKStringUtil;
import eo.ejb.cbs.cbsmsg.EDK0011B090CBSMsg;
import eo.ejb.cbs.cbsmsg.EDK0011B090CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341B517CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0341B517CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0591A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0591A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2541A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2541A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2541B002CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2541B002CBSMsg1List;

/**
 * 機器提供サービス契約予約一覧照会（オペレータ支援）CCです。<p>
 * <br>
 * @author 富士通
 *
 */
public class JKKKKTKSvcRsvIcrnOpsCC extends AbstractCommonComponent
{
	
	/** エラー情報 */
	private static final String ERROR_INFO = "ERROR_INFO";
	/** エラーコード */
	private static final String ERROR_CODE = "errCode";
	/** エラーメッセージ */
	private static final String ERROR_MESSAGE = "errMessage";
	
	
	/** サービス契約情報リスト */
	private static final String SVC_KEI_IF_LIST = "svc_kei_if_list";
	/** サービス契約番号 */
	private static final String SVC_KEI_NO = "svc_kei_no";
	/** 機器提供サービス契約情報リスト */
	private static final String KKTK_SVC_KEI_IF_LIST = "kktk_svc_kei_if_list";
	/** 機器提供サービス契約番号 */
	private static final String KKTK_SVC_KEI_NO = "kktk_svc_kei_no";
	/** 機器変更番号 */
	private static final String KIKI_CHG_NO = "kiki_chg_no";
	/** 親契約識別コード */
	private static final String OYA_KEI_SKBT_CD = "oya_kei_skbt_cd";
	/** サービス契約内訳番号 */
	private static final String SVC_KEI_UCWK_NO = "svc_kei_ucwk_no";
	/** サービス契約回線内訳番号 */
	private static final String SVC_KEI_KAISEN_UCWK_NO = "svc_kei_kaisen_ucwk_no";
	/** 機器提供サービス契約ステータス */
	private static final String KKTK_SVC_KEI_STAT = "kktk_svc_kei_stat";
	/** 機器提供サービス契約ステータス名称 */
	private static final String KKTK_SVC_KEI_STAT_NM = "kktk_svc_kei_stat_nm";
	/** 料金プランコード */
	private static final String PPLAN_CD = "pplan_cd";
	/** 料金プランコード名称 */
	private static final String PPLAN_CD_NM = "pplan_cd_nm";
	/** 宅内機器種別コード */
	private static final String TAKNKIKI_SBT_CD = "taknkiki_sbt_cd";
	/** 宅内機器型式コード */
	private static final String TAKNKIKI_MODEL_CD = "taknkiki_model_cd";
	/** 製造番号 */
	private static final String KIKI_SEIZO_NO = "kiki_seizo_no";
	/** 出荷年月日 */
	private static final String SHUKKA_YMD = "shukka_ymd";
	/** 工事案件実施年月日 */
	private static final String KOJIAK_JSSI_YMD = "kojiak_jssi_ymd";
	/** プラン開始年月日 */
	private static final String PLAN_STAYMD = "plan_staymd";
	/** 機器返却年月日 */
	private static final String KIKI_RTN_YMD = "kiki_rtn_ymd";

	
	/** テンプレートID(EKK2541B002) 割賦契約履歴一覧照会 */
	private static final String TEMPLATE_ID_EKK2541B002 = "EKK2541B002";
	/** 宅内機器種別コード（L1：クレードル(タブレット用)） */
	private static final String TAKNKIKI_SBT_CD_TABLET_CRADLE = "L1";
	/** 割賦契約一意照会 */
	private static final String TEMPLATE_ID_EKK2541A010 = "EKK2541A010";
	/** 契約機器配送対象物品一覧照会 */
	private static final String TEMPLATE_ID_EDK0011B090 = "EDK0011B090";
	
	/** 機器提供サービス契約一覧照会(接続機器情報)２ */
	private static final String TEMPLATE_ID_EKK0341B517 = "EKK0341B517";
	/** EKK0591A010_料金グループ一意照会 */
	private static final String TEMPLATE_ID_EKK0591A010 = "EKK0591A010";
	
	
	/** 空白 */
	private static final String EMPTY = "";

	
	/**
	 * 機器提供サービス契約一覧件数分、機器提供サービス契約履歴一覧を取得する。
	 * 
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return IRequestParameterReadWrite
	 * @throws Throwable 
	 */
	public IRequestParameterReadWrite execGet(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
		throws Throwable
	{
		
		@SuppressWarnings("unchecked")
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(fixedText);
		
		
		try 
		{
			// 単項目チェック
			if (!checkUnitParam(ccMsg))
			{
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, null);
				return param;
			}
			
			ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();		
	
			@SuppressWarnings("unchecked")
			List<HashMap<String, Object>> svcKeiIfList = (List<HashMap<String, Object>>) ccMsg.get(SVC_KEI_IF_LIST);
			
			for(HashMap<String, Object> svcKeiIfMap : svcKeiIfList)
			{
				
				// サービス契約番号を取得します。
				String svcKeiNo = (String)svcKeiIfMap.get(SVC_KEI_NO);
				
// ST-2021-000XXXX対応 20210603 ADD START
				boolean isKapKeiInfoCached = false;
// ST-2021-000XXXX対応 20210603 ADD END
				CAANMsg[] kapKeiInfoMsg = null;
				
// ST-2021-000XXXX対応 20210603 DEL START
// 下に移動
//				// サービス契約番号が設定されている場合取得します。
//				if(!"".equals(svcKeiNo))
//				{
//					kapKeiInfoMsg = getKapKeiInfo(handle, scCall, param, fixedText, svcKeiNo);
//				}
// ST-2021-000XXXX対応 20210603 DEL END
	
				
				// 取得したサービス契約番号より機器提供サービス契約一覧情報を取得します。
				CAANMsg[] ekk0341b517cbsMsg = execEKK0341B517(handle, scCall, param, fixedText, svcKeiNo);
				
				ArrayList<HashMap<String,Object>> dataList = new ArrayList<HashMap<String,Object>>();
				
				// 取得結果をループします。
				for (CAANMsg childTemplate : ekk0341b517cbsMsg)
				{
// ANK-4030-01-00対応 20210611 星野 ADD START
					// 予約取消年月日が設定されているレコードは交換取消済であるため処理対象外とする
					String rsvClYmd = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.RSV_CL_YMD));
					if(!JKKStringUtil.isNullBlank(rsvClYmd))
					{
						continue;
					}
// ANK-4030-01-00対応 20210611 星野 ADD END
					
					HashMap<String, Object> dataMap = new HashMap<String, Object>();
					
					String kktk_svc_kei_no = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KKTK_SVC_KEI_NO));
					String kiki_chg_no = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KIKI_CHG_NO));
					String pcrsCd = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.PCRS_CD_KKTK));
					String pplanCd = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.PPLAN_CD));
					String taknkiki_sbt_cd = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.TAKNKIKI_SBT_CD));
					String mskmDtlNo = getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.MSKM_DTL_NO));
	
					// 機器提供サービス契約一覧照会(接続機器情報)明細.機器提供サービス契約番号
					dataMap.put(KKTK_SVC_KEI_NO, kktk_svc_kei_no);
					
					// 機器変更番号
					dataMap.put(KIKI_CHG_NO, kiki_chg_no);
					
					// 親契約識別コード
					dataMap.put(OYA_KEI_SKBT_CD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.OYA_KEI_SKBT_CD)));
					
					// サービス契約内訳番号
					dataMap.put(SVC_KEI_UCWK_NO, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.SVC_KEI_UCWK_NO)));
					
					// サービス契約回線内訳番号
					dataMap.put(SVC_KEI_KAISEN_UCWK_NO, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO)));
					
					// 機器提供サービス契約ステータス
					dataMap.put(KKTK_SVC_KEI_STAT, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KKTK_SVC_KEI_STAT)));
					
					// 機器提供サービス契約ステータス名
					dataMap.put(KKTK_SVC_KEI_STAT_NM, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KKTK_SVC_KEI_STAT_NM)));
					
					// 料金プランコード
					dataMap.put(PPLAN_CD, pplanCd);
					
					CAANMsg ekk0591A010cbsMsg = execEKK0591A010(handle, scCall, param, fixedText, pcrsCd, pplanCd);
					// 料金プランコード名称
					if(ekk0591A010cbsMsg != null)
					{
						dataMap.put(PPLAN_CD_NM, getNullToStr(ekk0591A010cbsMsg.getString(EKK0591A010CBSMsg1List.PPLAN_NM)));
					}
					else
					{
						dataMap.put(PPLAN_CD_NM, "");
					}
					
					// 宅内機器種別コード
					dataMap.put(TAKNKIKI_SBT_CD, taknkiki_sbt_cd);
					
					// 宅内機器型式コード
					dataMap.put(TAKNKIKI_MODEL_CD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.TAKNKIKI_MODEL_CD)));
					
					// 機器製造番号
					dataMap.put(KIKI_SEIZO_NO, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KIKI_SEIZO_NO)));
					
					// 出荷年月日
					dataMap.put(SHUKKA_YMD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.SHUKKA_YMD)));
					
					// 工事案件実施年月日
					dataMap.put(KOJIAK_JSSI_YMD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.KOJIAK_JSSI_YMD)));
					
					// プラン開始年月日
					dataMap.put(PLAN_STAYMD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.PLAN_STAYMD)));
					
					// 機器返却年月日
					dataMap.put(KIKI_RTN_YMD, getNullToStr(childTemplate.getString(EKK0341B517CBSMsg1List.HMPIN_KURAIRE_YMD)));
					
					
					
// ST-2021-000XXXX対応 20210603 ADD START
					// タブレット・クレードルの場合のみ割賦引継の考慮を行う
					String kktkSvcCd = getNullToStr( childTemplate.getString(EKK0341B517CBSMsg1List.KKTK_SVC_CD) );
					if(JKKStrConst.KKTK_SVC_CD_TABLET.equals(kktkSvcCd) || JKKStrConst.KKTK_SVC_CD_TABLET_CRADLE.equals(kktkSvcCd) )
					{
						// 割賦契約情報の取得はサービス契約番号ごとに1回のみ行う
						if(!isKapKeiInfoCached){
							// サービス契約番号が設定されている場合取得します。
							if(!"".equals(svcKeiNo))
							{
								kapKeiInfoMsg = getKapKeiInfo(handle, scCall, param, fixedText, svcKeiNo);
							}
							isKapKeiInfoCached = true;
						}
// ST-2021-000XXXX対応 20210603 ADD END
						
						//// 割賦引継の場合の出荷日を取得します。
						String kapHktgShukkaYmd = getKapHktgShukkaYmd(handle, param, fixedText, scCall, kapKeiInfoMsg, kktk_svc_kei_no, kiki_chg_no, taknkiki_sbt_cd, mskmDtlNo);
						
						// 出荷日が取得できた場合、マップ上の出荷日を上書きする
						if (!"".equals(kapHktgShukkaYmd))
						{
							dataMap.put(SHUKKA_YMD, kapHktgShukkaYmd);
						}
						
// ST-2021-000XXXX対応 20210603 ADD START
					}
// ST-2021-000XXXX対応 20210603 ADD END
					
					
					
					
					dataList.add(dataMap);
				}
				svcKeiIfMap.put(KKTK_SVC_KEI_IF_LIST, dataList);
				
			}
			
			// 件数結果チェック
			boolean isEmpty = true;
			for(HashMap<String, Object> svcKeiIfMap : svcKeiIfList)
			{
				@SuppressWarnings("unchecked")
				List<HashMap<String,Object>> kktkSvcKeiIfList = (List<HashMap<String, Object>>) svcKeiIfMap.get(KKTK_SVC_KEI_IF_LIST);
				if( kktkSvcKeiIfList != null && !kktkSvcKeiIfList.isEmpty() )
				{
					isEmpty = false;
					break;
				}
			}
			if(isEmpty)
			{
				List<Map<String, String>> errList = new ArrayList<Map<String, String>>();
				errList.add(getEmptyErrInfMap());
				ccMsg.put(ERROR_INFO, errList);
	
				
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, null);
				return param;
	
			}
			
			
			// 正常終了
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_0000);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, null);
		}
		catch (SCCallException scCallEx) 
		{
			// システムエラーを設定する
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_9000);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, JKKStrConst.RETURN_MESSAGE_SYSTEM_ERROR);
			throw new CCException("サービスインターフェース呼び出しでエラーが発生しました。", scCallEx);
		}

		return param;
	}

	private String getKapHktgShukkaYmd(
		SessionHandle handle,
		IRequestParameterReadWrite param, 
		String fixedText,
		ServiceComponentRequestInvoker scCall, 
		CAANMsg[] kapKeiInfoMsg,
		String kktk_svc_kei_no, 
		String kiki_chg_no,
		String taknkiki_sbt_cd, 
		String mskmDtlNo
	) throws Exception 
	{
		String shukkaYmd = "";

		// サービス契約番号に紐付く、割賦契約情報を取得します。
		if(kapKeiInfoMsg != null && 0 < kapKeiInfoMsg.length)
		{
			// 取得結果を検索し、設定する
			for(CAANMsg childMsg : kapKeiInfoMsg )
			{
				// 機器提供サービス契約番号
				String kap_kktk_svc_no = getNullToStr(childMsg.getString(EKK2541B002CBSMsg1List.KKTK_SVC_KEI_NO_KK2541));
				// 登録時機器変更番号
				String add_ji_kiki_chg_no = getNullToStr(childMsg.getString(EKK2541B002CBSMsg1List.ADD_JI_KIKI_CHG_NO_KK2541));
				
				if(kktk_svc_kei_no.equals(kap_kktk_svc_no) && kiki_chg_no.equals(add_ji_kiki_chg_no))
				{
					String hktgiMotoKapKeiNo = getNullToStr(childMsg.getString(EKK2541B002CBSMsg1List.HKTGI_MOTO_KAP_KEI_NO_KK2541));
					if(!"".equals(hktgiMotoKapKeiNo))
					{
						shukkaYmd = getShukkaYmd(handle, scCall, param, fixedText, hktgiMotoKapKeiNo);
					}
					break;
				}
			}
		}
		
		// クレードルの場合
		if(TAKNKIKI_SBT_CD_TABLET_CRADLE.equals(taknkiki_sbt_cd))
		{
			shukkaYmd = getCradleShukkaYmd(handle, scCall, param, fixedText, kapKeiInfoMsg, mskmDtlNo);
		}
		return shukkaYmd;
	}
	
	/**
	 * 単項目チェックを行い、チェック結果を返します。
	 * <br>
	 * @param ccMsg
	 * @return チェックの判定
	 * @throws Exception
	 */
	private boolean checkUnitParam(Map<String, Object> ccMsg) throws Exception 
	{
		List<Map<String, String>> errList = new ArrayList<Map<String, String>>();
		
		
		@SuppressWarnings("unchecked")
		List<HashMap<String, Object>> svcKeiIfList = (List<HashMap<String, Object>>) ccMsg.get(SVC_KEI_IF_LIST);
		if( svcKeiIfList == null || svcKeiIfList.isEmpty() )
		{
			errList.add(getReqErrInfMap());
		}
		
		for(HashMap<String, Object> svcKeiIfMap : svcKeiIfList)
		{
			String svcKeiNo = (String) svcKeiIfMap.get(SVC_KEI_NO);
			
			if (svcKeiNo == null || svcKeiNo.trim().isEmpty())
			{
				errList.add(getReqErrInfMap());
			}
			
			else if (!HalfCharCheck.isEnNumber1Check(svcKeiNo)) 
			{
				errList.add(getFormErrInfMap());
			}
			
			else if (!LengthCheck.isLength1Check(svcKeiNo, 10))
			{
				errList.add(getLenErrInfMap());
			}
		}
		
		
		if (errList.size() > 0) 
		{
			ccMsg.put(ERROR_INFO, errList);
			return false;
		}
		
		return true;
	}

	/**
	 * 単項目チェックの必須エラーマップ作成メソッドです。
	 * <br>
	 * @return 必須エラーマップ
	 */
	private Map<String, String> getReqErrInfMap()
	{
		Map<String, String> returnMap = new HashMap<String, String>();
		
		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_1001);
		returnMap.put(ERROR_MESSAGE, EMPTY);
		
		return returnMap;
		
	}
	
	/**
	 * 単項目チェックの属性エラーマップ作成メソッドです。
	 * <br>
	 * @return 属性エラーマップ
	 */
	private Map<String, String> getFormErrInfMap()
	{
		Map<String, String> returnMap = new HashMap<String, String>();
		
		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_1002);
		returnMap.put(ERROR_MESSAGE, EMPTY);
		
		return returnMap;
	}
	
	/**
	 * 単項目チェックの桁数エラーマップ作成メソッドです。
	 * <br>
	 * @return 数エラーマップ
	 */
	private Map<String, String> getLenErrInfMap()
	{
		Map<String, String> returnMap = new HashMap<String, String>();

		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_1003);
		returnMap.put(ERROR_MESSAGE, EMPTY);

		return returnMap;
	}
	
	/**
	 * 件数結果チェックエラーマップ作成メソッドです。
	 * <br>
	 * @return 数エラーマップ
	 */
	private Map<String, String> getEmptyErrInfMap()
	{
		Map<String, String> returnMap = new HashMap<String, String>();

		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_2001);
		returnMap.put(ERROR_MESSAGE, EMPTY);

		return returnMap;
	}
	
	
	/**
	 * パラメタがNullの場合空白を返却します。
	 * @param str 文字列
	 * @return str
	 */
	private String getNullToStr(String str)
	{
		if (str == null || "".equals(str.trim()))
		{
			return "";
		}
		return str.trim();
	}
	
	/**
	 * SC(サービスインターフェイス）を呼び出す。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param mappingData
	 * @return CAANMsg
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg callSC(SessionHandle handle, 
							ServiceComponentRequestInvoker scCall, 
							IRequestParameterReadWrite param, 
							String dataMapKey,
							Object[][] mappingData) throws Exception
	{
		HashMap<String, Object> paramMap = editInMsg(param, mappingData);
		
		Map<?, ?> result = scCall.run(paramMap, handle);
		
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg msg = templates[0];
		
		// リターンコード取得
		Object return_code = result.get(JCMConstants.RET_CD_INT_KEY);
		Integer status = msg.getInt(JCMConstants.STATUS_INT_KEY);
		
		editErrorInfoCom(param, templates, (Integer)return_code, dataMapKey, mappingData);
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if (errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(result, errList));
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(return_code.toString()) && 0 == status))
		{
			throw new SCCallException("戻り値不正", return_code.toString(), status);
		}
		return msg;
	}

	/**
	 * @param param
	 * @param mappingData
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException
	 */
	private HashMap<String, Object> editInMsg(IRequestParameterReadWrite param,
												Object[][] mappingData) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文ID
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		paramMap.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		paramMap.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());
		
		// 【取得元：ユーザエリア(コントロールマップ)】
		// 依頼先ホスト名
		paramMap.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		
		CAANMsg template = new CAANMsg(String.format("eo.ejb.cbs.cbsmsg.%sCBSMsg", (String)mappingData[0][1]));
		
		// オペレータID
		template.set(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		// 運用日付
		template.set(JCMConstants.OPERATE_DATE_KEY, param.getControlMapData(SCControlMapKeys.OPE_DATE));
		// 運用日時
		template.set(JCMConstants.OPERATE_DATETIME_KEY, param.getControlMapData(SCControlMapKeys.OPE_TIME));
		
		for (int i = 0; i < mappingData.length; i++)
		{
			if ("".equals(mappingData[i][1]))
			{
				template.setNull((String)mappingData[i][0]);
			}
			else
			{
				template.set((String)mappingData[i][0], mappingData[i][1]);
			}
		}
		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);
		return paramMap;
	}

	/**
	 * 
	 * @param param
	 * @param templates
	 * @param returnCode
	 * @param dataMapKey
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editErrorInfoCom(IRequestParameterReadWrite param,
														CAANMsg[] templates, 
														int returnCode,
														String dataMapKey,
														Object[][] mappingData) throws RequestParameterException
	{
		// 本来はサービスインターフェイス分の処理が必要
		CAANMsg template = templates[0];
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (returnCode != 0)
		{
			templateStatus = 9000;
		}
		
		if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", templateStatus)) == null)
		{
			templateStatus = 0;
		}
		
		int bpStatus = 0;
		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		if (obj == null)
		{
			bpStatus = -1;
		}
		else
		{
			bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
		}
		
		if (templateStatus > bpStatus)
		{
			// BPにサービスコンポーネントのステータスを設定する。
			String formatStatus = String.format("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}
		HashMap<String, String> inMap = null;
		// ユーザデータ情報
		inMap = (HashMap<String, String>)param.getData(dataMapKey);
		
		for (int i = 0; i < mappingData.length; i++)
		{
			if (((String)mappingData[i][0]).startsWith("key_"))
			{
				if (!template.isNull(mappingData[i][0] + "_err"))
				{
					if (!inMap.containsKey(mappingData[i][0] + "_err"))
					{
						inMap.put(mappingData[i][0] + "_err", template.getString(mappingData[i][0] + "_err"));
					}
				}
			}
		}
		return param;
	}
	
	/**
	 * 割賦契約履歴一覧照会の取得
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param svcKeiNo
	 * @return CAANMsg[]
	 * @throws Exception
	 */
	private CAANMsg[] getKapKeiInfo(SessionHandle handle, 
												ServiceComponentRequestInvoker scCall, 
												IRequestParameterReadWrite param, 
												String dataMapKey,
												String svcKeiNo) throws Exception
	{
		
		// ***** EKK2541B002（割賦契約履歴一覧照会）*****
		Object[][] EKK2541B002IN = {
			{EKK2541B002CBSMsg.TEMPLATEID,       TEMPLATE_ID_EKK2541B002},
			{EKK2541B002CBSMsg.FUNC_CODE,        "1"},
			{EKK2541B002CBSMsg.KEY_SVC_KEI_NO,   svcKeiNo},
		};
		
		CAANMsg[] EKK2541B002cbsMsg1list = callSC(handle, scCall, param, dataMapKey, EKK2541B002IN).getCAANMsgList(EKK2541B002CBSMsg.EKK2541B002CBSMSG1LIST);
		
		if(EKK2541B002cbsMsg1list == null || EKK2541B002cbsMsg1list.length == 0)
		{
			return null;
		}
		
		return EKK2541B002cbsMsg1list;
	}
	
	/**
	 * 出荷年月日を取得します。
	 * 
	 * @param handle
	 * @param param
	 * @param dataMapKey
	 * @param ccMsg
	 * @param scCall
	 * @param kapKeiNo
	 * @return
	 * @throws Exception
	 */
	private String getShukkaYmd(SessionHandle handle,
										ServiceComponentRequestInvoker scCall,
										IRequestParameterReadWrite param,
										String dataMapKey,
										 String kapKeiNo) throws Exception
	{
		String shukkaYmd = "";
		
		// 割賦契約一意照会を取得します。
		CAANMsg ekk2541a010cbsMsg = execEKK2541A010(handle, scCall, param, dataMapKey, kapKeiNo);
		
		if(ekk2541a010cbsMsg == null)
		{
			return "";
		}
		
		String kktkSvcKeiNo = getNullToStr(ekk2541a010cbsMsg.getString(EKK2541A010CBSMsg1List.KKTK_SVC_KEI_NO));
		
		// 契約機器配送対象物品一覧照会を取得します。
		CAANMsg[] edk0011b090cbsMsg = execEDK0011B090(handle, scCall, param, dataMapKey, kktkSvcKeiNo);
		
		if(edk0011b090cbsMsg == null)
		{
			return "";
		}
		
		for (CAANMsg msg : edk0011b090cbsMsg) {
			
			String haisoStat = getNullToStr(msg.getString(EDK0011B090CBSMsg1List.HAISO_STAT));
			
			// 配送ステータスが中止以外
			if("005".equals(haisoStat))
			{
				continue;
			}
			
			shukkaYmd = getNullToStr(msg.getString(EDK0011B090CBSMsg1List.SHUKKA_YMD));
		}
		
		return shukkaYmd;
	}
	
	/**
	 * 割賦契約一意照会を取得します。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param kapKeiNo
	 * @return
	 * @throws Exception
	 */
	private CAANMsg execEKK2541A010(SessionHandle handle, 
											ServiceComponentRequestInvoker scCall, 
											IRequestParameterReadWrite param, 
											String dataMapKey,
											String kapKeiNo) throws Exception
	{
		// 割賦契約一意照会の取得
		// ***** EKK2541A010（割賦契約一意照会）*****
		Object[][] ekk2541a010IN = {
				{ EKK2541A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK2541A010 },
				{ EKK2541A010CBSMsg.FUNC_CODE, "2" },
				{ EKK2541A010CBSMsg.KEY_KAP_KEI_NO, kapKeiNo },
				{ EKK2541A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null) },
		};
		
		CAANMsg[] ekk2541a010cbsMsg1list = callSC(handle, scCall, param, dataMapKey, ekk2541a010IN).getCAANMsgList(EKK2541A010CBSMsg.EKK2541A010CBSMSG1LIST);
		
		if(ekk2541a010cbsMsg1list == null || ekk2541a010cbsMsg1list.length == 0)
		{
			return null;
		}
		
		return ekk2541a010cbsMsg1list[0];
	}
	
	/**
	 * 契約機器配送対象物品一覧照会を取得します。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param kktkSvcKeiNo
	 * @return
	 * @throws Exception
	 */
	private CAANMsg[] execEDK0011B090(SessionHandle handle, 
											ServiceComponentRequestInvoker scCall, 
											IRequestParameterReadWrite param, 
											String dataMapKey,
											String kktkSvcKeiNo) throws Exception
	{
		// ***** EDK0011B090（契約機器配送対象物品一覧照会）*****
		Object[][] edk0011b090IN = { 
				{ EDK0011B090CBSMsg.TEMPLATEID, TEMPLATE_ID_EDK0011B090 }, 
				{ EDK0011B090CBSMsg.FUNC_CODE, "1" },
				{ EDK0011B090CBSMsg.KEY_HAISO_NO, "" }, 
				{ EDK0011B090CBSMsg.KEY_HAISO_TAIBPIN_NO, "" },
				{ EDK0011B090CBSMsg.KEY_KKTK_SVC_KEI_NO, kktkSvcKeiNo } 
		};
		
		CAANMsg[] edk0011b090cbsMsg1list = callSC(handle, scCall, param, dataMapKey, edk0011b090IN).getCAANMsgList(EDK0011B090CBSMsg.EDK0011B090CBSMSG1LIST);
		
		if(edk0011b090cbsMsg1list == null || edk0011b090cbsMsg1list.length == 0)
		{
			return null;
		}
		
		return edk0011b090cbsMsg1list;
	}
	
	/**
	 * 割賦引継されたクレードルの場合、同時に引継がれたタブレットの出荷日を取得します。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param kapKeiInfoMsg
	 * @param mskmDtlNo
	 * @param dataMapKey
	 * @param kikiMap
	 * @return 出荷日
	 * @throws Exception
	 */
	private String getCradleShukkaYmd(SessionHandle handle,
											ServiceComponentRequestInvoker scCall,
											IRequestParameterReadWrite param,
											String fixedText,
											CAANMsg[] kapKeiInfoMsg,
											String mskmDtlNo)
											throws Exception {
		// 出荷年月日
		String shukkaYmd = "";
		
		// サービス契約番号に紐付く、割賦契約情報を取得します。
		if(kapKeiInfoMsg != null && 0 < kapKeiInfoMsg.length)
		{
			// 取得結果を検索し、設定する
			for(CAANMsg childMsg : kapKeiInfoMsg )
			{
				// 機器提供サービス契約の申込明細番号
				String kap_mskm_dtl_no = getNullToStr(childMsg.getString(EKK2541B002CBSMsg1List.MSKM_DTL_NO_KK2541));
				
				// 申込明細番号が違う場合は処理しません。
				if(!mskmDtlNo.equals(kap_mskm_dtl_no))
				{
					continue;
				}
				
				// 引継元割賦契約番号を取得します。
				String hktgiMotoKapKeiNo = getNullToStr(childMsg.getString(EKK2541B002CBSMsg1List.HKTGI_MOTO_KAP_KEI_NO_KK2541));
				
				// 引継元割賦契約番号がある場合
				if(!"".equals(hktgiMotoKapKeiNo))
				{
					// 出荷年月日を取得します。
					shukkaYmd = getShukkaYmd(handle, scCall, param, fixedText, hktgiMotoKapKeiNo);
					break;
				}
			}
		}
		
		return shukkaYmd;
	}
	
	
	/**
	 * 機器提供サービス契約一覧照会(接続機器情報)２を取得します。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param kktkSvcKeiNo
	 * @return
	 * @throws Exception
	 */
	private CAANMsg[] execEKK0341B517(SessionHandle handle, 
											ServiceComponentRequestInvoker scCall, 
											IRequestParameterReadWrite param, 
											String dataMapKey,
											String svcKeiNo) throws Exception
	{
		// ***** EKK0341B517（機器提供サービス契約一覧照会(接続機器情報)２）*****
		Object[][] ekk0341b517IN = { 
				{ EKK0341B517CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0341B517 }, 
				{ EKK0341B517CBSMsg.FUNC_CODE, "2" },
				{ EKK0341B517CBSMsg.KEY_SVC_KEI_NO, svcKeiNo } 
		};
		
		CAANMsg[] ekk0341b517cbsMsg1list = callSC(handle, scCall, param, dataMapKey, ekk0341b517IN).getCAANMsgList(EKK0341B517CBSMsg.EKK0341B517CBSMSG1LIST);
		
		if(ekk0341b517cbsMsg1list == null || ekk0341b517cbsMsg1list.length == 0)
		{
			return new CAANMsg[]{};
		}
		
		return ekk0341b517cbsMsg1list;
	}
	
	/**
	 * 料金プラン一意照会を実行します。
	 * <br>
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param fixedText
	 * @param cd_sbt_cd
	 * @param cd_div
	 * @return
	 * @throws Throwable
	 */
	private CAANMsg execEKK0591A010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall, 
									IRequestParameterReadWrite param, 
									String fixedText,
									String pcrsCd,
									String pplanCd ) throws Throwable
	{
		
		Object[][] EKK0591A010IN = {
				{ EKK0591A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0591A010 },
				{ EKK0591A010CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1 },
				{ EKK0591A010CBSMsg.KEY_PCRS_CD, pcrsCd },
				{ EKK0591A010CBSMsg.KEY_PPLAN_CD, pplanCd }
		};
		
		CAANMsg[] EKK0591A010cbsMsgList = callSC(handle, scCall, param, fixedText, EKK0591A010IN).getCAANMsgList(EKK0591A010CBSMsg.EKK0591A010CBSMSG1LIST);
		
		if(EKK0591A010cbsMsgList == null || EKK0591A010cbsMsgList.length == 0)
		{
			return null;
		}
		
		return EKK0591A010cbsMsgList[0];
	}

}
