/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKAdchgFixTajigsKeiIdtCC
*   ソースファイル名：JKKAdchgFixTajigsKeiIdtCC.java
*   作成者          ：富士通
*   日付            ：2020年07月02日
*＜機能概要＞
*   住所変更確定他事業者契約異動通知CCです。
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*	v50.00.00	2020/07/03	FJ）三原	新規作成(【ANK-3754-00-00】トビラフォン対応)
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
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.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.ejb.common.JSYejbLog;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JKKStringUtil;
import eo.ejb.cbs.cbsmsg.EKK0351A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0351A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0371C050CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2101B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2101B001CBSMsg1List;

/**
 * 住所変更確定他事業者契約異動通知CCです。<p>
 * <br>
 * @author FJ
 */
public class JKKAdchgFixTajgsKeiIdtCC extends AbstractCommonComponent
{
	/** 入力項目 住所変更番号 */
	private static final String PARAM_ADCHG_NO = "adchg_no";
	
	/** 入力項目 異動区分 */
	private static final String PARAM_TRN_DIV = "trn_div";
	
	/** 番号変更＿住所変更明細マップ項目 変更前識別番号 */
	private static final String NO_CHANGE_ADCHG_DTL_MAP_CHBF_SKBT_NO = "chbf_skbt_no";
	
	/** 番号変更＿住所変更明細マップ項目 変更後識別番号 */
	private static final String NO_CHANGE_ADCHG_DTL_MAP_CHAF_SKBT_NO = "chaf_skbt_no";
	
	/** オプションサービス契約マップ（B135）項目 オプションサービス契約番号 */
	private static final String OP_SVC_KEI_MAP_B135_OP_SVC_KEI_NO = "op_svc_kei_no";
	
	/** オプションサービス契約マップ（B135）項目 サービス契約内訳番号 */
	private static final String OP_SVC_KEI_MAP_B135_SVC_KEI_UCWK_NO = "svc_kei_ucwk_no";
	
	/** オプションサービス契約マップ（B135）項目 更新年月日時分秒 */
	//private static final String OP_SVC_KEI_MAP_B135_UPD_DTM = "upd_dtm";
	
	/** オプションサービス契約マップ（B135）項目 申込明細番号 */
	private static final String OP_SVC_KEI_MAP_B135_MSKM_DTL_NO = "mskm_dtl_no";
	
	/** オプションサービス契約<電話>情報変更マップ項目 オプションサービス契約番号 */
	private static final String OP_SVC_KEI_TEL_INFO_CHG_MAP_OP_SVC_KEI_NO = "op_svc_kei_no";
	
	/** オプションサービス契約<電話>情報変更マップ項目 他事業者契約異動通知登録解約フラグ */
	private static final String OP_SVC_KEI_TEL_INFO_CHG_MAP_TAJGS_KEI_IDT_ADD_DSL_FLG = "tajgs_kei_idt_add_dsl_flg";
	
	/** オプションサービス契約<電話>情報変更マップ項目 異動区分 */
	private static final String OP_SVC_KEI_TEL_INFO_CHG_MAP_IDO_DIV = "ido_div";
	
	/** オプションサービス契約<電話>情報変更マップ項目 更新年月日時分秒(更新前) */
	//private static final String OP_SVC_KEI_TEL_INFO_CHG_MAP_UPD_DTM_BF = "upd_dtm_bf";
	
	/** オプションサービス契約<電話>情報変更マップ項目 申込明細番号 */
	private static final String OP_SVC_KEI_TEL_INFO_CHG_MAP_MSKM_DTL_NO = "mskm_dtl_no";
	
	/** 処理区分 登録依頼 */
	private static final String TRN_DIV_ADD_0 = "0";
	
	/** 処理区分 解約依頼 */
	private static final String TRN_DIV_DSL_1 = "1";
	
	/** エラーメッセージ */
	private static final String ERR_MSG = "INVALID_RETURN_MESSAGE";
	
	/** SC呼び出し部品 */
	ServiceComponentRequestInvoker scCall = null;

	/**
	 * 住所変更確定他事業者契約異動通知処理を行います。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @throws Throwable 
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite executeTajgsKeiIdt(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		if (param == null)
		{
			// 処理終了
			return param;
		}
		
		// 初期処理
		init(param, fixedText);
		
		HashMap<String, Object> trgtData = (HashMap<String, Object>)param.getData(fixedText);
		
		if (trgtData != null)
		{
			// 実行判定フラグが""(値なし)または"0"(実行しない)の場合
			if ("".equals((String)trgtData.get("exec_jdg_flg")) || "0".equals((String)trgtData.get("exec_jdg_flg")))
			{
				// 処理終了
				return param;
			}
		}
		else
		{
			// 処理終了
			return param;
		}
		
		HashMap<String, Object> inMap = new HashMap<String, Object>();
		
		// パラメータチェック処理
		paramCheck(param, fixedText, inMap);
		
		if (inMap != null)
		{
			// メイン処理
			main(handle, param, fixedText, inMap);
		}
		
		return param;
	}

	/**
	 * 住所変更確定他事業者契約異動通知CCの初期処理です。
	 * <br>
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @throws Throwable 
	 */
	private void init(IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない。
		if (null == this.scCall)
		{
			this.scCall = new ServiceComponentRequestInvoker();
		}
		
		// リターンコードに正常を設定
		param.setControlMapData(SCControlMapKeys.RETURN_CODE, JCMConstants.RET_NORMAL);
	}

	/**
	 * 住所変更確定他事業者契約異動通知CCのパラメータチェック処理です。
	 * 各パラメータの必須チェックのみを行います。
	 * チェックしてエラーがなければinMapにセットする。
	 * <br>
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param inMap 内部Map
	 * @throws Throwable 
	 */
	@SuppressWarnings("unchecked")
	private void paramCheck(IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> inMap)
	throws Throwable
	{
		if (param != null)
		{
			// リクエストパラメータの取得処理
			HashMap<String, Object> trgtData = (HashMap<String, Object>)param.getData(fixedText);
			
			// 処理区分
			setterWorkParam(PARAM_TRN_DIV, "0", trgtData, inMap);
			
			// 住所変更番号
			setterWorkParam(PARAM_ADCHG_NO, "0", trgtData, inMap);
		}
	}

	/**
	 * <dl>
	 * <dt>処理概要：
	 * <dd>keyに紐づく引数を内部mapへ保持<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param  key 
	 * @throws CCException 
	 */
	private void setterWorkParam(String key, String nullDiv, HashMap<String, Object> trgtData, HashMap<String, Object> inMap) throws CCException
	{
		String obj = (String) trgtData.get(key);
		
		if (!JKKStringUtil.isNullBlank(obj) || "1".equals(nullDiv))
		{
			printlnEjbLog(key + "=" + obj);
			inMap.put(key, obj);
		}
		else
		{
			printlnEjbLog(key + "=NULL");
			throw new CCException(key + "=NULL", new Exception());
		}
	}

	/**
	 * <dl>
	 * <dt>処理概要：
	 * <dd>デバッグログを出力します<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param dumpObj 出力するオブジェクト
	 */
	private void printlnEjbLog(Object dumpObj)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), dumpObj, null, null, null);
	}

	/**
	 * 住所変更確定他事業者契約異動通知処理のメイン処理です。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param inMap 内部Map
	 * @return true/false 正常/エラー
	 * @throws Throwable 
	 */
	private void main(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> inMap)
	throws Throwable
	{
		// inMapから処理区分を取得する(0：番号変更の新電話番号の開始依頼、1：番号変更の旧電話番号の解約依頼)
		String trnDiv = (String)inMap.get(PARAM_TRN_DIV);
		
		// inMapから住所変更番号を取得する
		String adchgNo = (String)inMap.get(PARAM_ADCHG_NO);
		
		// inMapから住所変更番号を取得できなければ終了。
		if ("".equals(adchgNo))
		{
			return ;
		}
		
		// 住所変更番号をもとに住所変更明細を取得(EKK2101B001)
		CAANMsg[] eKK2101B001MsgList = callEKK2101B001(handle, param, fixedText, adchgNo);
		
		if (eKK2101B001MsgList == null || eKK2101B001MsgList.length == 0)
		{
			// 住所変更明細を取得を取得できなかった場合は処理終了
			return ;
		}
		
		// 番号変更＿住所変更明細リスト
		ArrayList<HashMap<String, String>> noChgAdchgDtlList = new ArrayList<HashMap<String, String>>();
		
		// オプションサービス契約リスト（B135）(B135:あんしん発着信サービス)
		ArrayList<HashMap<String, String>> opSvcKeiList_B135 = new ArrayList<HashMap<String, String>>();
		
		// 住所変更明細分の繰り返し処理を行い、番号変更＿住所変更明細リスト、オプションサービス契約リスト（B135）を設定する。
		for (CAANMsg eKK2101B001Msg : eKK2101B001MsgList)
		{
			// 住所変更明細種別コードが"02"(サービス契約内訳番号)のレコードを取得する(番号変更のレコードを識別する)
			if (eKK2101B001Msg != null && "02".equals(eKK2101B001Msg.getString(EKK2101B001CBSMsg1List.ADCHG_DTL_SBT_CD)))
			{
				// 変更前識別番号を取得する
				String chbfSkbtNo = (String)eKK2101B001Msg.getString(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
				
				// 変更後識別番号を取得する
				String chafSkbtNo = (String)eKK2101B001Msg.getString(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
				
				// ################################## //
				// ## 番号変更レコードの取得・設定 ## //
				// ################################## //
				// 変更前識別番号が""(空)ではない、かつ、変更後識別番号が""(空)ではない、かつ、変更前識別番号と変更後識別番号が異なる場合、番号変更。
				if (chbfSkbtNo != null && !"".equals(chbfSkbtNo) && chafSkbtNo != null && !"".equals(chafSkbtNo) && !chbfSkbtNo.equals(chafSkbtNo))
				{
					// 番号変更＿住所変更明細マップ
					HashMap<String, String> noChgAdchgDtlMap = new HashMap<String, String>();
					
					// 番号変更＿住所変更明細マップに変更前識別番号を設定する
					noChgAdchgDtlMap.put(NO_CHANGE_ADCHG_DTL_MAP_CHBF_SKBT_NO, chbfSkbtNo);
					
					// 番号変更＿住所変更明細マップに変更後識別番号を設定する
					noChgAdchgDtlMap.put(NO_CHANGE_ADCHG_DTL_MAP_CHAF_SKBT_NO, chafSkbtNo);
					
					// 番号変更＿住所変更明細リストに番号変更＿住所変更明細マップを追加する
					noChgAdchgDtlList.add(noChgAdchgDtlMap);
				}
			}
			
			// 住所変更明細種別コードが"04"(オプションサービス契約番号)のレコードを取得する
			if (eKK2101B001Msg != null && "04".equals(eKK2101B001Msg.getString(EKK2101B001CBSMsg1List.ADCHG_DTL_SBT_CD)))
			{
				// 変更前識別番号を取得する(オプションサービス契約番号となる)
				String chbfSkbtNo = (String)eKK2101B001Msg.getString(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
				
				// オプションサービス契約番号をもとにオプションサービス契約一意照会の結果を取得
				CAANMsg eKK0351A010Msg = callEKK0351A010(handle, param, fixedText, chbfSkbtNo);
				
				// ################################################ //
				// ## オプションサービス契約レコードの取得・設定 ## //
				// ################################################ //
				if (eKK0351A010Msg != null)
				{
					// オプションサービス契約一意照会からオプションサービスコードを取得する
					String opSvcCd = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.OP_SVC_CD);
					
					// オプションサービス契約一意照会からオプションサービス契約ステータスを取得する
					String opSvcKeiStat = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.OP_SVC_KEI_STAT);
					
					// オプションサービス契約一意照会からサービス契約内訳番号を取得する
					String svcKeiUcwkNo = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.SVC_KEI_UCWK_NO);
					
					//// オプションサービス契約一意照会から最終更新年月日時分秒を取得する
					//String lastUpdDtm = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.LAST_UPD_DTM);
					
					// オプションサービス契約一意照会から申込明細番号を取得する
					String mskmDtlNo = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.MSKM_DTL_NO);
					
					// オプションサービスコードが"B135"(あんしん発着信サービス)である、かつ、
					// オプションサービス契約ステータスが"910"(解約済)、"920"(キャンセル済)ではない場合
					if (JKKStrConst.OP_SVC_CD_ANSN_HCS_SVC.equals(opSvcCd)
						&& (!JKKStrConst.OP_SVC_STAT_DSLZUMI.equals(opSvcKeiStat) && !JKKStrConst.OP_SVC_STAT_CANCELZUMI.equals(opSvcKeiStat)))
					{
						// オプションサービス契約マップ（B135）
						HashMap<String, String> opSvcKeiMap_B135 = new HashMap<String, String>();
						
						// オプションサービス契約マップ（B135）にオプションサービス契約番号を設定する
						opSvcKeiMap_B135.put(OP_SVC_KEI_MAP_B135_OP_SVC_KEI_NO, chbfSkbtNo);
						
						// オプションサービス契約マップ（B135）にサービス契約内訳番号を設定する
						opSvcKeiMap_B135.put(OP_SVC_KEI_MAP_B135_SVC_KEI_UCWK_NO, svcKeiUcwkNo);
						
						//// オプションサービス契約マップ（B135）に更新年月日時分秒を設定する
						//opSvcKeiMap_B135.put(OP_SVC_KEI_MAP_B135_UPD_DTM, lastUpdDtm);
						
						// オプションサービス契約マップ（B135）に申込明細番号を設定する
						opSvcKeiMap_B135.put(OP_SVC_KEI_MAP_B135_MSKM_DTL_NO, mskmDtlNo);
						
						// オプションサービス契約リスト（B135）にオプションサービス契約マップ（B135）を追加する
						opSvcKeiList_B135.add(opSvcKeiMap_B135);
					}
				}
			}
		}
		
		// オプションサービス契約リスト（B135）が空の場合、処理対象なしのため終了。
		if (opSvcKeiList_B135 == null || opSvcKeiList_B135.size() == 0)
		{
			return ;
		}
		
		// ################################################################## //
		// ## オプションサービス契約<電話>情報変更リスト設定処理(番号変更) ## //
		// ################################################################## //
		// 番号変更＿住所変更明細リストの変更前識別番号とオプションサービス契約リスト（B135）のサービス契約内訳番号が一致する場合、
		// サービス契約内訳番号に紐付く旧電話番号を取得する。(合わせて新電話番号を取得する。)
		
		// オプションサービス契約<電話>情報変更リスト
		ArrayList<HashMap<String, String>> opSvcKeiTelInfoChgList = new ArrayList<HashMap<String, String>>();
		
		if (noChgAdchgDtlList != null && noChgAdchgDtlList.size() > 0)
		{
			// 番号変更＿住所変更明細リスト分の繰り返し処理
			for (HashMap<String, String> noChgAdchgDtlMap : noChgAdchgDtlList)
			{
				// 番号変更＿住所変更明細マップの変更前識別番号(サービス契約内訳番号)
				String noChgAdchgDtlMapChbfSkbtNo = "";
				// 番号変更＿住所変更明細マップの変更後識別番号(サービス契約内訳番号)
				String noChgAdchgDtlMapChafSkbtNo = "";
				
				if (noChgAdchgDtlMap != null)
				{
					// 番号変更＿住所変更明細マップの変更前識別番号(サービス契約内訳番号)を取得する
					noChgAdchgDtlMapChbfSkbtNo = noChgAdchgDtlMap.get(NO_CHANGE_ADCHG_DTL_MAP_CHBF_SKBT_NO);
					
					// 番号変更＿住所変更明細マップの変更後識別番号(サービス契約内訳番号)を取得する
					noChgAdchgDtlMapChafSkbtNo = noChgAdchgDtlMap.get(NO_CHANGE_ADCHG_DTL_MAP_CHAF_SKBT_NO);
				}
				
				// オプションサービス契約リスト（B135）分の繰り返し処理
				for (HashMap<String, String>opSvcKeiMap_B135 : opSvcKeiList_B135)
				{
					// オプションサービス契約マップ（B135）のオプションサービス契約番号
					String opSvcKeiMapB135OpSvcKeiNo = "";
					
					// オプションサービス契約マップ（B135）のサービス契約内訳番号
					String opSvcKeiMapB135SvcKeiUcwkNo = "";
					
					//// オプションサービス契約マップ（B135）の更新年月日時分秒
					//String opSvcKeiMapB135UpdDtm = "";
					
					// オプションサービス契約マップ（B135）の申込明細番号
					String opSvcKeiMapB135MskmDtlNo = "";
					
					if (opSvcKeiMap_B135 != null)
					{
						// オプションサービス契約マップ（B135）のオプションサービス契約番号を取得する
						opSvcKeiMapB135OpSvcKeiNo = opSvcKeiMap_B135.get(OP_SVC_KEI_MAP_B135_OP_SVC_KEI_NO);
						
						// オプションサービス契約マップ（B135）のサービス契約内訳番号を取得する
						opSvcKeiMapB135SvcKeiUcwkNo = opSvcKeiMap_B135.get(OP_SVC_KEI_MAP_B135_SVC_KEI_UCWK_NO);
						
						//// オプションサービス契約マップ（B135）の更新年月日時分秒を取得する
						//opSvcKeiMapB135UpdDtm = opSvcKeiMap_B135.get(OP_SVC_KEI_MAP_B135_UPD_DTM);
						
						// オプションサービス契約マップ（B135）の申込明細番号を取得する
						opSvcKeiMapB135MskmDtlNo = opSvcKeiMap_B135.get(OP_SVC_KEI_MAP_B135_MSKM_DTL_NO);
					}
					
					// 処理区分が1：番号変更の旧電話番号の解約依頼の場合
					if (TRN_DIV_DSL_1.equals(trnDiv))
					{
						// 番号変更＿住所変更明細マップの「変更前識別番号」とオプションサービス契約マップ（B135）のサービス契約内訳番号が等しい場合
						if (noChgAdchgDtlMapChbfSkbtNo != null && noChgAdchgDtlMapChbfSkbtNo.equals(opSvcKeiMapB135SvcKeiUcwkNo))
						{
							// オプションサービス契約<電話>情報変更マップ編集処理
							opSvcKeiTelInfoChgList.add(editOpSvcKeiTelInfoChgMap(opSvcKeiMapB135OpSvcKeiNo, trnDiv, opSvcKeiMapB135MskmDtlNo));
						}
					}
					// 処理区分が0：番号変更の新電話番号の開始依頼の場合
					else if (TRN_DIV_ADD_0.equals(trnDiv))
					{
						// 番号変更＿住所変更明細マップの「変更後識別番号」とオプションサービス契約マップ（B135）のサービス契約内訳番号が等しい場合
						if (noChgAdchgDtlMapChafSkbtNo != null && noChgAdchgDtlMapChafSkbtNo.equals(opSvcKeiMapB135SvcKeiUcwkNo))
						{
							// オプションサービス契約<電話>情報変更マップ編集処理
							opSvcKeiTelInfoChgList.add(editOpSvcKeiTelInfoChgMap(opSvcKeiMapB135OpSvcKeiNo, trnDiv, opSvcKeiMapB135MskmDtlNo));
						}
					}
					
				}
			}
		}
		
		// ########################################## //
		// ## オプションサービス契約<電話>情報変更 ## //
		// ########################################## //
		// オプションサービス契約<電話>情報変更リストが""(空)ではない場合
		if (opSvcKeiTelInfoChgList != null && opSvcKeiTelInfoChgList.size() > 0)
		{
			//オプションサービス契約<電話>情報変更リスト分の繰り返し処理
			for (HashMap<String, String> opSvcKeiTelInfoChgMap : opSvcKeiTelInfoChgList)
			{
				if (opSvcKeiTelInfoChgMap != null)
				{
					// オプションサービス契約＜電話＞情報変更を実行する
					callEKK0371C050(handle, param, fixedText, opSvcKeiTelInfoChgMap);
				}
			}
		}
	}

	/**
	 * オプションサービス契約＜電話＞情報変更マップ編集処理です。
	 * <br>
	 * @param opSvcKeiMapB135OpSvcKeiNo オプションサービス契約番号(B135)
	 * @param trnDiv 処理区分
	 * @param opSvcKeiMapB135MskmDtlNo 申込明細番号
	 * @return opSvcKeiTelInfoChgMap オプションサービス契約電話情報変更マップ
	 * @throws Throwable 
	 */
	private HashMap<String, String> editOpSvcKeiTelInfoChgMap
	(
		String opSvcKeiMapB135OpSvcKeiNo
		, String trnDiv
		, String opSvcKeiMapB135MskmDtlNo
	)
	{
		// オプションサービス契約<電話>情報変更マップ
		HashMap<String, String> opSvcKeiTelInfoChgMap = new HashMap<String, String>();
		
		// オプションサービス契約<電話>情報変更マップにオプションサービス契約番号を設定する
		opSvcKeiTelInfoChgMap.put(OP_SVC_KEI_TEL_INFO_CHG_MAP_OP_SVC_KEI_NO, opSvcKeiMapB135OpSvcKeiNo);
		
		// オプションサービス契約<電話>情報変更マップに異動区分を設定する
		opSvcKeiTelInfoChgMap.put(OP_SVC_KEI_TEL_INFO_CHG_MAP_IDO_DIV, JKKStrConst.CD00576_ADCHG_FIX);
		
		// オプションサービス契約<電話>情報変更マップに他事業者契約異動通知登録解約フラグを設定する
		opSvcKeiTelInfoChgMap.put(OP_SVC_KEI_TEL_INFO_CHG_MAP_TAJGS_KEI_IDT_ADD_DSL_FLG, trnDiv);
		
		// オプションサービス契約<電話>情報変更マップに申込明細番号を設定する
		opSvcKeiTelInfoChgMap.put(OP_SVC_KEI_TEL_INFO_CHG_MAP_MSKM_DTL_NO, opSvcKeiMapB135MskmDtlNo);
		
		return opSvcKeiTelInfoChgMap;
	}

	/**
	 * オプションサービス契約＜電話＞情報変更処理サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param opSvcKeiTelInfoChgMap オプションサービス契約<電話>情報変更マップ
	 * @throws Throwable
	 */
	private void callEKK0371C050(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, HashMap<String, String> opSvcKeiTelInfoChgMap)
	throws Throwable
	{
		// 上り情報を生成
		CAANMsg template = new CAANMsg(EKK0371C050CBSMsg.class.getName());
		
		// nullマッピングを実施
		fillCAANMSGNullMapping(template, new EKK0371C050CBSMsg().getContents());
		
		// 共通部を設定
		editBasicCmn(param, template);
		
		// テンプレートID(SIFのID)
		template.set(EKK0371C050CBSMsg.TEMPLATEID, "EKK0371C050");
		
		// 機能コード
		template.set(EKK0371C050CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1);
		
		// オプションサービス契約<電話>情報変更マップからオプションサービス契約番号を取得する
		String opSvcKeiNo = (String)opSvcKeiTelInfoChgMap.get(OP_SVC_KEI_TEL_INFO_CHG_MAP_OP_SVC_KEI_NO);
		// オプションサービス契約番号
		template.set(EKK0371C050CBSMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		
		// オプションサービス契約<電話>情報変更マップから申込明細番号を取得する
		String mskmDtlNo = (String)opSvcKeiTelInfoChgMap.get(OP_SVC_KEI_TEL_INFO_CHG_MAP_MSKM_DTL_NO);
		// 申込明細番号
		template.set(EKK0371C050CBSMsg.MSKM_DTL_NO, mskmDtlNo);
		
		// オプションサービス契約<電話>情報変更マップから異動区分を取得する
		String idoDiv = (String)opSvcKeiTelInfoChgMap.get(OP_SVC_KEI_TEL_INFO_CHG_MAP_IDO_DIV);
		// 異動区分
		template.set(EKK0371C050CBSMsg.IDO_DIV, idoDiv);
		
		// 更新年月日時分秒を取得する
		String updDtmBf = getUpdDtmBf(handle, param, fixedText, opSvcKeiNo);
		
		// 更新年月日時分秒(更新前)
		template.set(EKK0371C050CBSMsg.UPD_DTM_BF, updDtmBf);
		
		// オプションサービス契約<電話>情報変更マップから他事業者契約異動通知登録解約フラグを取得する
		String tajgsKeiIdtAddDslFlg = (String)opSvcKeiTelInfoChgMap.get(OP_SVC_KEI_TEL_INFO_CHG_MAP_TAJGS_KEI_IDT_ADD_DSL_FLG);
		
		// 他事業者契約異動通知登録解約フラグ
		template.set(EKK0371C050CBSMsg.TAJGS_KEI_IDT_ADD_DSL_FLG, tajgsKeiIdtAddDslFlg);
		
		HashMap<String, Object> inMap = editInMsgBasicCmn(param, template);
		
		// サービスインターフェース呼び出し
		callSvcInter(handle, param, fixedText, inMap, new EKK0371C050CBSMsg().getContents());
	}

	/**
	 * サービスインターフェース呼び出し処理です。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param siInMap サービスインターフェースの入力マップ
	 * @param contents サービスインターフェースのテンプレート項目の配列
	 * @return 業務データ
	 * @throws Throwable 
	 */
	private CAANMsg callSvcInter(
			SessionHandle handle
			,IRequestParameterReadWrite param
			,String fixedText
			,HashMap<String, Object> siInMap
			,Object[][] contents
	) throws Throwable
	{
		// サービスインターフェースの呼び出し
		Map<?, ?> rsltMap = this.scCall.run(siInMap, handle);
		
		// エラーマッピング処理
		editResultRP(rsltMap, param, fixedText, contents);
		// エラーチェック処理
		errChk(rsltMap);
		// 業務データ取得処理
		CAANMsg workData = getWorkCAANMsg(rsltMap);
		
		return workData;
	}

	/**
	 * エラーチェック処理です。
	 * <br>
	 * @param msgList サービスインタフェース実行結果
	 * @throws SCCallException 
	 */
	private void errChk(Map<?, ?> msgList) throws SCCallException
	{
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg template = templates[0];
		
		// リターンコード取得
		Integer returnCode = (Integer)msgList.get(JCMConstants.RET_CD_INT_KEY);
		
		// ステータス取得
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if ((0 != returnCode.intValue()) || (0 != templateStatus))
		{
			String errMsg = ERR_MSG;
			throw new SCCallException(errMsg, String.valueOf(returnCode), templateStatus);
		}
	}

	/**
	 * 業務データの取得処理です。
	 * <br>
	 * @param workMapKey 業務データのマップキー
	 * @param rslt SVIFの実行結果データ
	 * @return 業務データ
	 */
	private CAANMsg getWorkCAANMsg(Map<?, ?> rslt)
	{
		CAANMsg[] templates = (CAANMsg[])rslt.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg parentTemplate = templates[0];
		
		return parentTemplate;
	}
	
	/**
	 * サービスコンポーネント実行後に、IRequestParameterReadWriteに必要なデータをマッピングする
	 * <br>
	 * @param msgList CAANMsgクラス
	 * @param param 業務データ取得・書込用I/F
	 * @param fixedText ユーザ任意文字列
	 * @param contents サービスインターフェースのテンプレート項目の配列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editResultRP(
			 Map<?, ?> msgList
			,IRequestParameterReadWrite param
			,String fixedText
			,Object[][] contents
	) throws Throwable 
	{
		
		// SCからの戻り値からCAANMsgを取得する。
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg template = templates[0];
		
		// リターンコード取得
		Integer returnCode = (Integer)msgList.get(JCMConstants.RET_CD_INT_KEY);
		
		// ステータス取得
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (returnCode.intValue() != 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 inMap = (HashMap)param.getData(fixedText);
		
		// ユーザデータ情報にエラー情報をマッピング
		for(int i = 0 ; contents != null && i < contents.length ; i++)
		{
			String element = null;
			element = (String)contents[i][0];
			if (element.indexOf("_err") > 0)
			{
				if (!template.isNull(element))
				{
					if (!inMap.containsKey(element))
					{
						inMap.put(element, template.getString(element));
					}
				}
			}
		}
		
		// エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if(errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(msgList, errList));
		
		return param;
	}
	
	/**
	 * サービスI/F実行用の上り情報を生成する
	 * 
	 * @param param リクエストパラメータ
	 * @param template 条件の設定先
	 * @return S/I上り情報
	 * @throws RequestParameterException
	 * @exception RequestParameterException
	 */
	private HashMap<String, Object> editInMsgBasicCmn(IRequestParameterReadOnly param, CAANMsg template)
	throws RequestParameterException 
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		/* SCインプット共通データ */
		// **********************************************
		// 【取得元：電文ヘッダ(ヘッダ)】
		// **********************************************
		// 電文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[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);
		
		return paramMap;
	}
	
	/**
	 * 条件部の共通する項目の設定
	 * @param param リクエストパラメータ
	 * @param template template 条件の設定先
	 * @throws RequestParameterException
	 */
	private void editBasicCmn(IRequestParameterReadOnly param, CAANMsg template)
	throws RequestParameterException
	{
		// オペレータID
		Object operatorId = param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);
		
		// 運用日付
		Object operateDate = param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);
		
		// 運用日時
		Object operateDateTime = param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);
	}
	
	/**
	 * 持ちうるフィールドにNullマッピングで埋める
	 * 
	 * @param msg 対象クラス
	 * @param contents 対応クラスのフィールド列挙
	 */
	private void fillCAANMSGNullMapping(CAANMsg msg, Object[][] contents)
	{
		// 要素ごとのループ
		for(int i = 0 ; i < contents.length ; i++)
		{
			Object element = null;
			// キーに該当する箇所の取得
			element = contents[i][0];
			// Nullでマッピング
			msg.setNull((String)element);
		}
	}

	/**
	 * 住所変更明細一覧照会サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param adchgNo 住所変更番号
	 * @return 住所変更明細一覧照会結果
	 * @throws Throwable
	 */
	private CAANMsg[] callEKK2101B001(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, String adchgNo)
	throws Throwable
	{
		// ■上り情報を生成
		CAANMsg template = new CAANMsg(EKK2101B001CBSMsg.class.getName());
		
		// nullマッピングを実施
		fillCAANMSGNullMapping(template, new EKK2101B001CBSMsg().getContents());
		
		// 共通部を設定
		editBasicCmn(param, template);
		
		// テンプレートID(SIFのID)
		template.set(EKK2101B001CBSMsg.TEMPLATEID, "EKK2101B001");
		
		// 機能コード
		template.set(EKK2101B001CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1);
		
	    // ＫＥＹ＿住所変更番号
		template.set(EKK2101B001CBSMsg.KEY_ADCHG_NO, adchgNo);
		
		HashMap<String, Object> inMap = editInMsgBasicCmn(param, template);
		
		// ■サービスインターフェース呼び出し
		CAANMsg rsltMsg = callSvcInter(handle, param, fixedText, inMap, new EKK2101B001CBSMsg().getContents());
		
		// ■結果を返却
		CAANMsg[] rsltMsgList = rsltMsg.getCAANMsgList(EKK2101B001CBSMsg.EKK2101B001CBSMSG1LIST);
		
		return rsltMsgList;
	}

	/**
	 * オプションサービス契約一意照会処理サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約一意照会結果
	 * @throws Throwable
	 */
	private CAANMsg callEKK0351A010(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, String opSvcKeiNo)
	throws Throwable
	{
		// 上り情報を生成
		CAANMsg template = new CAANMsg(EKK0351A010CBSMsg.class.getName());
		
		// nullマッピングを実施
		fillCAANMSGNullMapping(template, new EKK0351A010CBSMsg().getContents());
		
		// 共通部を設定
		editBasicCmn(param, template);
		
		// テンプレートID(SIFのID)
		template.set(EKK0351A010CBSMsg.TEMPLATEID, "EKK0351A010");
		
		// 機能コード
		template.set(EKK0351A010CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_2);
		
	    // ＫＥＹ＿オプションサービス契約番号
		template.set(EKK0351A010CBSMsg.KEY_OP_SVC_KEI_NO, opSvcKeiNo);
		
	    // ＫＥＹ＿予約適用年月日
		template.set(EKK0351A010CBSMsg.KEY_RSV_APLY_YMD, JCCBPCommon.getOpeDate(null));
		
		HashMap<String, Object> inMap = editInMsgBasicCmn(param, template);
		
		// サービスインターフェース呼び出し
		CAANMsg rsltMsg = callSvcInter(handle, param, fixedText, inMap, new EKK0351A010CBSMsg().getContents());
		
		// 結果を返却
		CAANMsg[] rsltMsgList = rsltMsg.getCAANMsgList(EKK0351A010CBSMsg.EKK0351A010CBSMSG1LIST);
		
		if (rsltMsgList != null && rsltMsgList.length > 0)
		{
			return rsltMsgList[0];
		}
		
		return new CAANMsg();
	}
	
	/**
	 * オプションサービス契約一意照会処理サービスを実行し、更新前更新年月日時分秒を取得します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return 更新前更新年月日時分秒
	 * @throws Throwable 
	 */
	private String getUpdDtmBf(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, String opSvcKeiNo) throws Throwable
	{
		if (opSvcKeiNo != null && !"".equals(opSvcKeiNo))
		{
			CAANMsg eKK0351A010Msg = callEKK0351A010(handle, param, fixedText, opSvcKeiNo);
			
			if (eKK0351A010Msg != null)
			{
				String lastUpdDtm = (String)eKK0351A010Msg.getString(EKK0351A010CBSMsg1List.LAST_UPD_DTM);
				return lastUpdDtm;
			}
		}
		
		return "";
	}
}
