/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKCsCrsOpchInfOperateCC
*   ソースファイル名：JKKCsCrsOpchInfOperateCC.java
*   作成者          ：FJ
*   日付            ：2024/12/25
*＜機能概要＞
*   CSコース用オプションチャンネル情報操作の共通コンポーネント
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v74.00.00   2024/12/25   FJ）中川    【ANK-4592-00-00】テレビ新コース（スカパー用）導入対応
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.text.ParseException;
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.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
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.bp.x21.cc.exception.SCCallException;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JKKCommonUtil;
import eo.common.util.JKKStringUtil;
import eo.common.util.JPCDateUtil;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0351B016CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0351B016CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK1681B004CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1681B503CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK3541A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK3541A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK3561C010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK3561D010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK3561E010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK3571D010CBSMsg;
import eo.ejb.cbs.cbsmsg.EZM0321A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EZM0321A010CBSMsg1List;

/**
 * CSコース用オプションチャンネル情報操作の共通コンポーネントクラスです。
 * <br>
 * @author 富士通
 */
public class JKKCsCrsOpchInfOperateCC extends AbstractCommonComponent 
{
	/** サービス契約一意照会 */
	private static final String TEMPLATE_ID_EKK0081A010 = "EKK0081A010";
	/** 異動予約一覧照会(異動予約状態コード) */
	private static final String TEMPLATE_ID_EKK1681B004 = "EKK1681B004";
	/** CASカード管理一意照会 */
	private static final String TEMPLATE_ID_EKK3541A010 = "EKK3541A010";
	/** 業務パラメータ管理一意照会 */
	private static final String TEMPLATE_ID_EZM0321A010 = "EZM0321A010";
	/** オプションサービス契約一覧照会(CSコース) */
	private static final String TEMPLATE_ID_EKK0351B016 = "EKK0351B016";
	/** CAS番号対象オプションサービス契約登録 */
	private static final String TEMPLATE_ID_EKK3561D010 = "EKK3561D010";
	/** CAS番号対象オプションサービス契約変更 */
	private static final String TEMPLATE_ID_EKK3561C010 = "EKK3561C010";
	/** CAS番号対象オプションサービス契約物理削除 */
	private static final String TEMPLATE_ID_EKK3561E010 = "EKK3561E010";
	/** CAS番号対象オプションサービス契約履歴登録 */
	private static final String TEMPLATE_ID_EKK3571D010 = "EKK3571D010";
	
	/** テンプレートID(業務パラメータ管理一意照会) ＫＥＹ＿業務パラメータID */
	private static final String KEY_WORK_PARAM_ID_EZM0321A010 = "KK_CS_COURSE_OPCH";
	
	/** 機能コード 更新 */
	private static final String FUNC_CD_CHG = "1";
	/** 機能コード チェックのみ */
	private static final String FUNC_CD_CHK = "2";
	/** 機能コード 照会 */
	private static final String FUNC_CD_SEARCH = "3";
	
	/** 変更区分 登録 */
	private static final String CHG_DIV_ADD = "1";
	/** 変更区分 削除 */
	private static final String CHG_DIV_DEL = "2";
	/** 変更区分 取消 */
	private static final String CHG_DIV_CSL = "3";
	
	/** エラーコード 登録状態エラー */
	private static final String ERR_CD_ADD_STAT = "04";
	/** エラーコード 削除状態エラー */
	private static final String ERR_CD_DEL_STAT = "05";
	/** エラーコード 取消状態エラー */
	private static final String ERR_CD_CSL_STAT = "09";
	/** エラーコード 異常 */
	private static final String ERR_CD_SYSTEM_ERR = "99";
	
	/** スカパー適用基準年月日区分 即時 */
	private static final String SPTV_APLY_STDARDYMD_DIV_SOKUJI = "1";
	/** スカパー適用基準年月日区分 次月 */
	private static final String SPTV_APLY_STDARDYMD_DIV_JIGETSU = "2";
	/** スカパー適用基準年月日区分 次々月 */
	private static final String SPTV_APLY_STDARDYMD_DIV_JIJIGETSU = "3";
	
	/** 相手システムID バックヤード */
	private static final String AITE_SYSID_BACKYARD = "3";
	/** 相手システムID フロント */
	private static final String AITE_SYSID_FRONT = "4";
	
	/** 鍵閉め理由コード 個別鍵閉め */
	private static final String KEYCLS_RSN_CD_KOBETSU = "1";

	/**
	 * CSコース用オプションチャンネル情報操作実行処理です。<br>
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable 
	 * @exception Exceptionがスローされます。
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite operateOpchInf(SessionHandle handle, 
			IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		String dataMapKey = fixedText;
		
		// CSコース用オプションチャンネル情報操作CCマップ
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(dataMapKey);
		if (ccMsg == null)
		{
			return param;
		}
		
		// 機能コード
		String funcCd = (String)ccMsg.get("func_cd");
		
		// 機能コードが"1"(更新)、"2"(チェックのみ)、"3"(照会)以外の場合、処理を終了する
		if(!(FUNC_CD_CHG.equals(funcCd) || FUNC_CD_CHK.equals(funcCd) || FUNC_CD_SEARCH.equals(funcCd)))
		{
			ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
			return param;
		}
		
		// 戻り値初期化
		// エラーコード
		ccMsg.put("err_cd", "");
		
		// CATV顧客番号
		ccMsg.put("catv_cust_no", "");
		
		// 料金コース
		ccMsg.put("pcrs", "");
		
		// 料金コース名称
		ccMsg.put("pcrs_nm", "");
		
		// 料金プラン
		ccMsg.put("pplan", "");
		
		// 料金プラン名称
		ccMsg.put("pplan_nm", "");
		
		// 新料金コース
		ccMsg.put("new_pcrs", "");
		
		// エラーオプションサービスコード
		ccMsg.put("err_op_svc_cd", "");
		
		// エラーオプションサービスコード名称
		ccMsg.put("err_op_svc_cd_nm", "");
		
		// サービス契約ステータス
		ccMsg.put("svc_kei_stat", "");
		
		// スカパー連携ステータス
		ccMsg.put("sptv_rnk_stat", "");
		
		// オプションリスト
		ccMsg.put("op_list", new ArrayList<HashMap<String, Object>>());
		
		// エラーコード(正常)を設定
		ccMsg.put("err_cd", null);
		
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない）
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		
		// 照会処理を実行
		searchOpch(handle, scCall, param, dataMapKey, ccMsg);
		
		// エラーコードにnull(正常)以外が設定されている場合、処理を終了する
		if(!JKKCommonUtil.isNull((String)ccMsg.get("err_cd")))
		{
			return param;
		}
		
		// 照会モードの場合、処理を終了する
		if(FUNC_CD_SEARCH.equals(funcCd))
		{
			return param;
		}
		
		// エラーチェック処理を実行
		errChk(funcCd, param, ccMsg);
		
		// エラーコードにnull(正常)以外が設定されている場合、処理を終了する
		if(!JKKCommonUtil.isNull((String)ccMsg.get("err_cd")))
		{
			return param;
		}
		
		// オプション操作処理を実行
		operateOpch(handle, scCall, param, dataMapKey, ccMsg);
		
		return param;

	}
	
	/**
	 * 照会処理を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param ccMsg データ情報
	 * @throws Throwable
	 */
	private void searchOpch(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									HashMap<String, Object> ccMsg) throws Throwable
	{
		// サービス契約番号
		String svcKeiNo = (String)ccMsg.get("svc_kei_no");
		
		// CASカード番号
		String cascdNo = (String)ccMsg.get("cascd_no");
		
		// 業務パラメータ設定値(CSコース用オプションチャンネル)
		String csCrsOpch = "";
		
		// 料金コースコード
		String pcrsCd = "";
		
		// オプションリスト
		ArrayList<HashMap<String, Object>> opList = new ArrayList<HashMap<String, Object>>();
		
		// CASカード番号が未設定の場合、処理を終了する
		if (JKKStringUtil.isNullBlank(cascdNo))
		{
			ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
			return;
		}
		
		// サービス契約一意照会
		CAANMsg ekk0081a010Msg = execEKK0081A010(handle, scCall, param, dataMapKey, svcKeiNo);
		if (ekk0081a010Msg != null)
		{
			// ■サービス契約情報
			// サービス契約ステータス
			ccMsg.put("svc_kei_stat", ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.SVC_KEI_STAT));
			
			// サービスコード
			ccMsg.put("svc_cd", ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.SVC_CD));
			
			// 料金コース
			pcrsCd = ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.PCRS_CD);
			ccMsg.put("pcrs", pcrsCd);
			
			// 料金コース名称
			ccMsg.put("pcrs_nm", ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.PCRS_CD_NM));
			
			// 料金プラン
			ccMsg.put("pplan", ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.PPLAN_CD));
			
			// 料金プラン名称
			ccMsg.put("pplan_nm", ekk0081a010Msg.getString(EKK0081A010CBSMsg1List.PPLAN_CD_NM));
		}
		
		// 異動予約一覧照会(異動予約状態コード)
		CAANMsg ekk1681b004Msg = execEKK1681B004(handle, scCall, param, dataMapKey, svcKeiNo);
		if (ekk1681b004Msg != null)
		{
			// ■異動予約情報
			// 新料金コース
			ccMsg.put("new_pcrs", ekk1681b004Msg.getString(EKK1681B503CBSMsg1List.NEW_PCRS_CD));
		}
		
		// CASカード管理一意照会
		CAANMsg ekk3541a010Msg = execEKK3541A010(handle, scCall, param, dataMapKey, cascdNo);
		if (ekk3541a010Msg != null)
		{
			// ■CASカード管理情報
			// CATV顧客番号
			ccMsg.put("catv_cust_no", ekk3541a010Msg.getString(EKK3541A010CBSMsg1List.CATV_CUST_NO));
			
			// スカパー連携ステータス
			ccMsg.put("sptv_rnk_stat", ekk3541a010Msg.getString(EKK3541A010CBSMsg1List.SPTV_RNK_STAT));
		}
		
		// 業務パラメータ管理一意照会
		CAANMsg ezm0321a010Msg = execEZM0321A010(handle, scCall, param, dataMapKey);
		if (ezm0321a010Msg != null)
		{
			// ■業務パラメータ管理情報
			// 業務パラメータ設定値(CSコース用オプションチャンネル)
			csCrsOpch = ezm0321a010Msg.getString(EZM0321A010CBSMsg1List.WORK_PARAM_SETTE_VALUE);
		}
		
		// 業務パラメータ設定値、または料金コースが未設定の場合、処理を終了する
		if (JKKStringUtil.isNullBlank(csCrsOpch) || JKKStringUtil.isNullBlank(pcrsCd))
		{
			ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
			return;
		}
		
		// オプションサービス契約一覧照会（CSコース）
		CAANMsg[] ekk0351b016MsgList = execEKK0351B016(handle, scCall, param, dataMapKey, csCrsOpch, cascdNo, pcrsCd);
		
		if (ekk0351b016MsgList != null && ekk0351b016MsgList.length > 0)
		{
			// ■オプションサービス契約情報
			for (int i = 0; i < ekk0351b016MsgList.length; i++)
			{
				opList.add(new HashMap<String, Object>());
				HashMap<String, Object> opMap = opList.get(i);

				// オプションサービス契約番号
				opMap.put("op_svc_kei_no", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_KEI_NO));
				
				// オプションステータス
				opMap.put("op_stat", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_KEI_STAT));
				
				// オプションステータス名称
				opMap.put("op_stat_nm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_KEI_STAT_NM));
				
				// オプションサービスコード
				opMap.put("op_svc_cd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_CD));
				
				// オプションサービスコード名称
				opMap.put("op_svc_cd_nm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_NM));
				
				// 料金コース
				opMap.put("pcrs", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.PCRS_CD));
				
				// 料金コース名称
				opMap.put("pcrs_nm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.PCRS_CD_NM));
				
				// 料金プラン
				opMap.put("pplan", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.PPLAN_CD));
				
				// 料金プラン名称
				opMap.put("pplan_nm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.PPLAN_CD_NM));
				
				// サービス開始年月日
				opMap.put("svc_staymd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.DSP_SVCTK_STAYMD));
				
				// サービス課金開始年月日
				opMap.put("svc_chrg_staymd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.SVC_CHRG_STAYMD));
				
				// スカパー連携ステータス
				opMap.put("sptv_rnk_stat", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.SPTV_RNK_STAT));
				
				// スカパー連携ステータス名称
				opMap.put("sptv_rnk_stat_nm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.SPTV_RNK_STAT_NM));
				
				// 鍵開け日付
				opMap.put("keyopn_ymd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.KEYOPN_YMD));
				
				// 鍵閉め日付
				opMap.put("keycls_ymd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.KEYCLS_YMD));
				
				// オプションサービス備考
				opMap.put("op_svc_biko", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.OP_SVC_BIKO));
				
				// CASカード番号
				opMap.put("cascd_no", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.CASCD_NO));
				
				// CAS番号対象適用年月日
				opMap.put("cas_no_tg_aply_ymd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.CAS_NO_TG_APLY_YMD));
				
				// 鍵閉め理由コード
				opMap.put("keycls_rsn_cd", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.KEYCLS_RSN_CD));
				
				// 更新年月日時分秒
				opMap.put("upd_dtm", ekk0351b016MsgList[i].getString(EKK0351B016CBSMsg1List.UPD_DTM));
			}
		}
		
		// オプションリスト
		ccMsg.put("op_list", opList);
	}
	
	/**
	 * エラーチェックを行う。
	 * @param funcCd 機能コード
	 * @param param パラメーター
	 * @param ccMsg データ情報
	 * @return boolean
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	private void errChk(String funcCd, IRequestParameterReadWrite param,
									HashMap<String, Object> ccMsg) throws Throwable
	{
		// オプション更新リスト
		ArrayList<HashMap<String, Object>> opUpdList = (ArrayList<HashMap<String, Object>>)ccMsg.get("op_upd_list");
		
		if (opUpdList != null && opUpdList.size() > 0)
		{
			for (int i = 0; i < opUpdList.size(); i++)
			{
				// 変更区分
				String chgDiv = (String)opUpdList.get(i).get("chg_div");
				
				// スカパー適用基準年月日区分
				String sptvAplyStdardymdDiv = (String)opUpdList.get(i).get("sptv_aply_stdardymd_div");
				
				// 利用終了日
				String useEndymd = (String)opUpdList.get(i).get("use_endymd");
				
				// 処理対象オプションサービス契約番号
				String opSvcKeiNo = (String)opUpdList.get(i).get("op_svc_kei_no");
				
				// 変更対象オプションサービスコード
				String opSvcCd = (String)opUpdList.get(i).get("op_svc_cd");
				
				// 変更区分が未設定の場合、
				// または変更区分が"1"(登録)、"2"(削除)、"3"(取消)以外の場合、
				// または変更区分が"1"(登録)であり、かつスカパー適用基準年月日区分が"1"(即時)、"2"(次月)、"3"(次々月)以外の場合、
				// または変更区分が"3"(取消)であり、かつスカパー適用基準年月日区分が"1"(即時)以外の場合、
				// または変更区分が"2"(削除)であり、かつ利用終了日が未設定の場合、
				// またはオプションサービスコードが未設定の場合、
				// または「機能コードが"1"(更新)、または変更区分が"2"(削除)、"3"(取消)」であり、かつ処理対象オプションサービス契約番号が未設定の場合、
				// 処理を終了する。
				if(JKKStringUtil.isNullBlank(chgDiv)
					|| !(CHG_DIV_ADD.equals(chgDiv) || CHG_DIV_DEL.equals(chgDiv) || CHG_DIV_CSL.equals(chgDiv))
					|| (CHG_DIV_ADD.equals(chgDiv) && !(SPTV_APLY_STDARDYMD_DIV_SOKUJI.equals(sptvAplyStdardymdDiv) || SPTV_APLY_STDARDYMD_DIV_JIGETSU.equals(sptvAplyStdardymdDiv) || SPTV_APLY_STDARDYMD_DIV_JIJIGETSU.equals(sptvAplyStdardymdDiv)))
					|| (CHG_DIV_CSL.equals(chgDiv) && !SPTV_APLY_STDARDYMD_DIV_SOKUJI.equals(sptvAplyStdardymdDiv))
					|| (CHG_DIV_DEL.equals(chgDiv) && JKKStringUtil.isNullBlank(useEndymd))
					|| JKKStringUtil.isNullBlank(opSvcCd)
					|| ((FUNC_CD_CHG.equals(funcCd) || (CHG_DIV_DEL.equals(chgDiv) || CHG_DIV_CSL.equals(chgDiv))) && JKKStringUtil.isNullBlank(opSvcKeiNo)))
				{
					ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
					return;
				}
				
				// 状態チェック
				if(!statChk(param, ccMsg, opSvcKeiNo, chgDiv))
				{
					// オプションリスト
					ArrayList<HashMap<String, Object>> opList = (ArrayList<HashMap<String, Object>>)ccMsg.get("op_list");
					for(int j = 0; j < opList.size(); j++)
					{
						if(opSvcCd.equals((String)opList.get(j).get("op_svc_cd")))
						{
							// エラー対象オプションサービス契約のオプションサービスコード/名称を設定して返却する
							ccMsg.put("err_op_svc_cd", opSvcCd);
							ccMsg.put("err_op_svc_cd_nm", (String)opList.get(j).get("op_svc_cd_nm"));
							break;
						}
					}
					
					// エラーコードを設定
					if(CHG_DIV_ADD.equals(chgDiv))
					{
						// 登録状態エラー
						ccMsg.put("err_cd", ERR_CD_ADD_STAT);
					}
					else if(CHG_DIV_DEL.equals(chgDiv))
					{
						// 削除状態エラー
						ccMsg.put("err_cd", ERR_CD_DEL_STAT);
					}
					else if(CHG_DIV_CSL.equals(chgDiv))
					{
						// 取消状態エラー
						ccMsg.put("err_cd", ERR_CD_CSL_STAT);
					}
					else
					{
						// 異常
						ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
					}
					
					return;
				}
			}
		}
	}
	
	/**
	 * 状態チェックを行う。
	 * @param param パラメーター
	 * @param ccMsg データ情報
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param chgDiv 変更区分
	 * @return boolean
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	private boolean statChk(IRequestParameterReadWrite param, HashMap<String, Object> ccMsg,
									String opSvcKeiNo, String chgDiv) throws Throwable
	{
		// サービス契約ステータスチェック
		String svcKeiStat = (String)ccMsg.get("svc_kei_stat");
		if(!(JKKStrConst.CD00037_CNC_ZM.equals(svcKeiStat) || JKKStrConst.CD00037_SVCTK_CHU.equals(svcKeiStat)))
		{
			return false;
		}
		
		// スカパー連携ステータスチェック(CASカード管理)
		String sptvRnkStat1 = (String)ccMsg.get("sptv_rnk_stat");
		if(!(JKKStrConst.SPTV_RNK_STAT_KEIHENCHUKAGIAKEIRAIMAE.equals(sptvRnkStat1)
				|| JKKStrConst.SPTV_RNK_STAT_KEIHENCHUKAGIAKEIRAICHU.equals(sptvRnkStat1)
				|| JKKStrConst.SPTV_RNK_STAT_KEIHENCHUKAGIAKEERROR.equals(sptvRnkStat1)
				|| JKKStrConst.SPTV_RNK_STAT_KAGIAKEZUMI.equals(sptvRnkStat1)))
		{
			return false;
		}
		
		// オプションサービス契約ステータス/スカパー連携ステータスチェック(CAS番号対象オプションサービス契約)
		if(!CHG_DIV_ADD.equals(chgDiv))
		{
			// オプションリスト
			ArrayList<HashMap<String, Object>> opList = (ArrayList<HashMap<String, Object>>)ccMsg.get("op_list");
			String opSvcKeiStat = "";
			String sptvRnkStat2 = "";
			for(int i = 0; i < opList.size(); i++)
			{
				if(opSvcKeiNo.equals((String)opList.get(i).get("op_svc_kei_no")))
				{
					opSvcKeiStat = (String)opList.get(i).get("op_stat");
					sptvRnkStat2 = (String)opList.get(i).get("sptv_rnk_stat");
					break;
				}
			}
			if(!((CHG_DIV_DEL.equals(chgDiv) && JKKStrConst.OP_SVC_STAT_SVCTK_CHU.equals(opSvcKeiStat) && JKKStrConst.SPTV_RNK_STAT_KAGIAKEZUMI.equals(sptvRnkStat2))
				|| (CHG_DIV_CSL.equals(chgDiv)
					&& ((JKKStrConst.SPTV_RNK_STAT_KAGIAKEIRAIMAE.equals(sptvRnkStat2) && JKKStrConst.OP_SVC_STAT_TEIKETSUZUMI.equals(opSvcKeiStat))
						|| (JKKStrConst.SPTV_RNK_STAT_KAGISIMEIRAIMAE.equals(sptvRnkStat2) && JKKStrConst.OP_SVC_STAT_SVCTK_CHU.equals(opSvcKeiStat))))))
			{
				return false;
			}
		}
		
		// 料金コースチェック
		String pcrsCd = (String)ccMsg.get("pcrs");
		String newPcrsCd = (String)ccMsg.get("new_pcrs");
		if(!(JKKStrConst.CD00134_AC0.equals(pcrsCd)
				|| JKKStrConst.CD00134_AC1.equals(pcrsCd)
				|| JKKStrConst.CD00134_AC0.equals(newPcrsCd)
				|| JKKStrConst.CD00134_AC1.equals(newPcrsCd)))
		{
			return false;
		}
		
		return true;
	}
	
	/**
	 * オプション操作処理を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param ccMsg データ情報
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	private void operateOpch(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									HashMap<String, Object> ccMsg) throws Throwable
	{
		// オプション更新リスト
		ArrayList<HashMap<String, Object>> opUpdList = (ArrayList<HashMap<String, Object>>)ccMsg.get("op_upd_list");
		
		if(opUpdList != null && opUpdList.size() > 0)
		{
			
			
			for (int i = 0; i < opUpdList.size(); i++)
			{
				// 処理対象オプション更新リスト
				HashMap<String, Object> opUpdListTg = opUpdList.get(i);
				
				// オプションサービス契約番号
				String opSvcKeiNo = (String)opUpdListTg.get("op_svc_kei_no");
				
				// 変更区分
				String chgDiv = (String)opUpdListTg.get("chg_div");
				
				if(CHG_DIV_ADD.equals(chgDiv))
				{
					// オプション申込処理
					addOpch(handle, scCall, param, dataMapKey, ccMsg, opUpdListTg, opSvcKeiNo);
				}
				else
				{
					// 処理対象オプションリスト
					HashMap<String, Object> opListTg = new HashMap<String, Object>();
					ArrayList<HashMap<String, Object>> opList = (ArrayList<HashMap<String, Object>>)ccMsg.get("op_list");
					for(int j = 0; j < opList.size(); j++)
					{
						if(opSvcKeiNo.equals((String)opList.get(j).get("op_svc_kei_no")))
						{
							opListTg = opList.get(j);
							break;
						}
					}
					if(CHG_DIV_DEL.equals(chgDiv))
					{
						// オプション解約処理
						delOpch(handle, scCall, param, dataMapKey, ccMsg, opUpdListTg, opSvcKeiNo, opListTg);
					}
					else if(CHG_DIV_CSL.equals(chgDiv))
					{
						// オプション取消処理
						cslOpch(handle, scCall, param, dataMapKey, ccMsg, opSvcKeiNo, opListTg);
					}
				}
				
				// エラーコードにnull(正常)以外が設定されている場合、処理を終了する
				if(!JKKCommonUtil.isNull((String)ccMsg.get("err_cd")))
				{
					return;
				}
			}
		}
	}
	
	/**
	 * オプション申込処理を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param ccMsg データ情報
	 * @param opUpdListTg 処理対象オプション更新リスト
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @throws Throwable
	 */
	private void addOpch(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									HashMap<String, Object> ccMsg,
									HashMap<String, Object> opUpdListTg,
									String opSvcKeiNo) throws Throwable
	{
		// 機能コード
		String funcCd = (String)ccMsg.get("func_cd");
		
		// CASカード番号
		String cascdNo = (String)ccMsg.get("cascd_no");
		
		// スカパー連携ステータス
		String sptvRnkStat = JKKStrConst.SPTV_RNK_STAT_KAGIAKEIRAIMAE;
		
		// 運用日付
		String opeDate = JPCBPCommon.getOpeDate(null);
		
		// スカパー適用基準年月日区分
		String sptvAplyStdardymdDiv = (String)opUpdListTg.get("sptv_aply_stdardymd_div");
		
		// 鍵開け年月日
		String keyopnYmd = "";
		if(SPTV_APLY_STDARDYMD_DIV_SOKUJI.equals(sptvAplyStdardymdDiv))
		{
			// スカパー適用基準年月日区分が"1"(即時)の場合、運用日付を設定
			keyopnYmd = opeDate;
		}
		else if(SPTV_APLY_STDARDYMD_DIV_JIGETSU.equals(sptvAplyStdardymdDiv))
		{
			// スカパー適用基準年月日区分が"2"(次月)の場合、翌月１日-１日を設定
			keyopnYmd = getCurrentMonthFinalDay(opeDate);
		}
		else if(SPTV_APLY_STDARDYMD_DIV_JIJIGETSU.equals(sptvAplyStdardymdDiv))
		{
			// スカパー適用基準年月日区分が"3"(次々月)の場合、翌々月１日-１日を設定
			keyopnYmd = getNextMonthFinalDay(opeDate);
		}
		
		// 鍵閉め年月日
		String keyclsYmd = JKKStrConst.KARA;
		
		// CAS番号対象適用年月日
		String casNoTgAplyYmd = JKKStrConst.KARA;
		
		// 鍵閉め理由コード
		String keyclsRsnCd = JKKStrConst.KARA;
		
		// システム日付
		String sysDate = JCCBPCommon.getSysDateTimeStamp();
		
		// 機能コードが"2"(チェックのみ)の場合、S-IFの呼び出しを行わない
		if(!FUNC_CD_CHK.equals(funcCd))
		{
			// CAS番号対象オプションサービス契約登録
			execEKK3561D010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd);
			
			// CAS番号対象オプションサービス契約履歴登録
			execEKK3571D010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, sysDate, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd);
		}
	}
	
	/**
	 * オプション解約処理を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param ccMsg データ情報
	 * @param opUpdListTg 処理対象オプション更新リスト
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param opListTg 処理対象オプションリスト
	 * @throws Throwable
	 */
	private void delOpch(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									HashMap<String, Object> ccMsg,
									HashMap<String, Object> opUpdListTg,
									String opSvcKeiNo,
									HashMap<String, Object> opListTg) throws Throwable
	{
		// 機能コード
		String funcCd = (String)ccMsg.get("func_cd");
		
		// CASカード番号
		String cascdNo = (String)opListTg.get("cascd_no");
		
		// スカパー連携ステータス
		String sptvRnkStat = JKKStrConst.SPTV_RNK_STAT_KAGISIMEIRAIMAE;
		
		// 鍵開け年月日
		String keyopnYmd = (String)opListTg.get("keyopn_ymd");
		
		// 相手システムID
		String aiteSysid = (String)ccMsg.get("aite_sysid");
		
		// 利用終了日
		String useEndymd = (String)opUpdListTg.get("use_endymd");
		
		// 鍵閉め年月日
		String keyclsYmd = "";
		
		// 鍵閉め年月日
		if(AITE_SYSID_BACKYARD.equals(aiteSysid))
		{
			// 相手システムIDが"3"(バックヤード)の場合、利用終了日＋２日を設定
			keyclsYmd =  JPCDateUtil.addDay(useEndymd, 2);
		}
		else if(AITE_SYSID_FRONT.equals(aiteSysid))
		{
			// 相手システムIDが"4"(フロント)の場合、利用終了日の翌月１日を設定
			keyclsYmd = getNextMonthFirstDay(useEndymd);
		}
		else
		{
			// 相手システムIDが"3"(バックヤード)、"4"(フロント)以外の場合、処理を終了する
			ccMsg.put("err_cd", ERR_CD_SYSTEM_ERR);
			return;
		}
		
		// CAS番号対象適用年月日
		String casNoTgAplyYmd = (String)opListTg.get("cas_no_tg_aply_ymd");
		
		// 鍵閉め理由コード
		String keyclsRsnCd = KEYCLS_RSN_CD_KOBETSU;
		
		// 更新年月日時分秒(更新前)
		String updDtmBf = (String)opListTg.get("upd_dtm");
		
		// システム日付
		String sysDate = JCCBPCommon.getSysDateTimeStamp();
		
		// CAS番号対象オプションサービス契約変更
		execEKK3561C010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd, updDtmBf);
		
		// CAS番号対象オプションサービス契約履歴登録
		execEKK3571D010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, sysDate, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd);
	}
	
	/**
	 * オプション取消処理を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param ccMsg データ情報
	 * @param opUpdListTg 処理対象オプション更新リスト
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param opListTg 処理対象オプションリスト
	 * @throws Throwable
	 */
	private void cslOpch(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									HashMap<String, Object> ccMsg,
									String opSvcKeiNo,
									HashMap<String, Object> opListTg) throws Throwable
	{
		// 機能コード
		String funcCd = (String)ccMsg.get("func_cd");
		
		// CASカード番号
		String cascdNo = (String)opListTg.get("cascd_no");
		
		// スカパー連携ステータス
		String sptvRnkStat = (String)opListTg.get("sptv_rnk_stat");
		
		// 鍵開け年月日
		String keyopnYmd = (String)opListTg.get("keyopn_ymd");
		
		// CAS番号対象適用年月日
		String casNoTgAplyYmd = (String)opListTg.get("cas_no_tg_aply_ymd");
		
		// 更新年月日時分秒(更新前)
		String updDtmBf = (String)opListTg.get("upd_dtm");
		
		// システム日付
		String sysDate = JCCBPCommon.getSysDateTimeStamp();
		
		if(JKKStrConst.SPTV_RNK_STAT_KAGIAKEIRAIMAE.equals(sptvRnkStat))
		{
			// 鍵開け予約取消を行う
			// スカパー連携ステータス
			sptvRnkStat = JKKStrConst.SPTV_RNK_STAT_SAKUJO;
			
			// 鍵閉め年月日
			String keyclsYmd = (String)opListTg.get("keycls_ymd");
			
			// 鍵閉め理由コード
			String keyclsRsnCd = (String)opListTg.get("keycls_rsn_cd");
			
			// CAS番号対象オプションサービス契約物理削除
			execEKK3561E010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, updDtmBf);
			
			// CAS番号対象オプションサービス契約履歴登録
			execEKK3571D010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, sysDate, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd);
		}
		else if(JKKStrConst.SPTV_RNK_STAT_KAGISIMEIRAIMAE.equals(sptvRnkStat))
		{
			// 鍵閉め予約取消を行う
			// スカパー連携ステータス
			sptvRnkStat = JKKStrConst.SPTV_RNK_STAT_KAGIAKEZUMI;
			
			// 鍵閉め年月日
			String keyclsYmd = JKKStrConst.KARA;
			
			// 鍵閉め理由コード
			String keyclsRsnCd = JKKStrConst.KARA;
			
			// CAS番号対象オプションサービス契約変更
			execEKK3561C010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd, updDtmBf);
			
			// CAS番号対象オプションサービス契約履歴登録
			execEKK3571D010(handle, scCall, param, dataMapKey, funcCd, opSvcKeiNo, sysDate, cascdNo, sptvRnkStat, keyopnYmd, keyclsYmd, casNoTgAplyYmd, keyclsRsnCd);
		}
	}
	
	/**
	 * 翌月１日取得
	 * @param ymd
	 * @return 翌月１日
	 * @throws ParseException 
	 */
	private String getNextMonthFirstDay(String ymd) throws ParseException
	{
		// 翌月を取得
		String nextMonthDate = JPCDateUtil.addMonth(ymd, 1);
		String yearMonth = nextMonthDate.substring(0, 6);
		String retYmd = yearMonth + "01";
		
		return retYmd;
	}
	
	/**
	 * 翌月１日-１日取得
	 * @param ymd
	 * @return 翌月１日-１日
	 * @throws ParseException 
	 */
	private String getCurrentMonthFinalDay(String ymd) throws ParseException
	{
		// 翌月を取得
		String nextMonthDate = JPCDateUtil.addMonth(ymd, 1);
		String yearMonth = nextMonthDate.substring(0, 6);
		String nextMonthFirstDay = yearMonth + "01";
		String retYmd = JPCDateUtil.addDay(nextMonthFirstDay, -1);
		
		return retYmd;
	}
	
	/**
	 * 翌々月１日-１日取得
	 * @param ymd
	 * @return 翌々月１日-１日
	 * @throws ParseException 
	 */
	private String getNextMonthFinalDay(String ymd) throws ParseException
	{
		// 翌々月を取得
		String nextNextMonthDate = JPCDateUtil.addMonth(ymd, 2);
		String yearMonth = nextNextMonthDate.substring(0, 6);
		String nextNextMonthFirstDay = yearMonth + "01";
		String retYmd = JPCDateUtil.addDay(nextNextMonthFirstDay, -1);
		
		return retYmd;
	}
	
	/**
	 * サービス契約一意照会を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param svcKeiNo サービス契約番号
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK0081A010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String svcKeiNo) throws Throwable
	{
		CAANMsg result = null;
		
		Object[][] ekk0081a010In =
		{
				{EKK0081A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0081A010},
				{EKK0081A010CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_2},
				{EKK0081A010CBSMsg.KEY_SVC_KEI_NO, svcKeiNo},
				{EKK0081A010CBSMsg.KEY_GENE_ADD_DTM, ""},
				{EKK0081A010CBSMsg.KEY_RSV_APLY_YMD, JCCBPCommon.getOpeDate(null)},
		};
		
		CAANMsg ekk0081a010Msg = callSC(handle, scCall, param, dataMapKey, ekk0081a010In);
		
		CAANMsg[] ekk0081a010MsgList = ekk0081a010Msg.getCAANMsgList(EKK0081A010CBSMsg.EKK0081A010CBSMSG1LIST);
		
		if (ekk0081a010MsgList != null && ekk0081a010MsgList.length > 0)
		{
			result = ekk0081a010MsgList[0];
		}
		
		return result;
	}
	
	/**
	 * 異動予約一覧照会(異動予約状態コード)を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param svcKeiNo サービス契約番号
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK1681B004(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String svcKeiNo) throws Throwable
	{
		CAANMsg result = null;
		
		Object[][] ekk1681b004In =
		{
				{EKK1681B004CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK1681B004},
				{EKK1681B004CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
				{EKK1681B004CBSMsg.KEY_SVC_KEI_NO, svcKeiNo},
				{EKK1681B004CBSMsg.KEY_IDO_DIV, JKKStrConst.CD00576_00009},
				{EKK1681B004CBSMsg.KEY_IDO_RSV_STAT_CD, JKKStrConst.CD01168_IDO_RSV_STAT_CD_00 + 
					JKKStrConst.COMMA + JKKStrConst.CD01168_IDO_RSV_STAT_CD_03},
		};
		
		CAANMsg ekk1681b004Msg = callSC(handle, scCall, param, dataMapKey, ekk1681b004In);
		
		CAANMsg[] ekk1681b004MsgList = ekk1681b004Msg.getCAANMsgList(EKK1681B004CBSMsg.EKK1681B004CBSMSG1LIST);
		
		if (ekk1681b004MsgList != null && ekk1681b004MsgList.length > 0)
		{
			result = ekk1681b004MsgList[0];
		}
		
		return result;
	}
	
	/**
	 * CASカード管理一意照会を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param cascdNo CASカード番号
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK3541A010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String cascdNo) throws Throwable
	{
		CAANMsg result = null;
		
		Object[][] ekk3541a010In =
		{
				{EKK3541A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK3541A010},
				{EKK3541A010CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
				{EKK3541A010CBSMsg.KEY_CASCD_NO, cascdNo},
		};
		
		CAANMsg ekk3541a010Msg = callSC(handle, scCall, param, dataMapKey, ekk3541a010In);
		
		CAANMsg[] ekk3541a010MsgList = ekk3541a010Msg.getCAANMsgList(EKK3541A010CBSMsg.EKK3541A010CBSMSG1LIST);
		
		if (ekk3541a010MsgList != null && ekk3541a010MsgList.length > 0)
		{
			result = ekk3541a010MsgList[0];
		}
		
		return result;
	}
	
	/**
	 * 業務パラメータ管理一意照会を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEZM0321A010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey) throws Throwable
	{
		CAANMsg result = null;
		
		Object[][] ezm0321a010In =
		{
				{EZM0321A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EZM0321A010},
				{EZM0321A010CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
				{EZM0321A010CBSMsg.KEY_WORK_PARAM_ID, KEY_WORK_PARAM_ID_EZM0321A010},
		};
		
		CAANMsg ezm0321a010Msg = callSC(handle, scCall, param, dataMapKey, ezm0321a010In);
		
		CAANMsg[] ezm0321a010MsgList = ezm0321a010Msg.getCAANMsgList(EZM0321A010CBSMsg.EZM0321A010CBSMSG1LIST);
		
		if (ezm0321a010MsgList != null && ezm0321a010MsgList.length > 0)
		{
			result = ezm0321a010MsgList[0];
		}
		
		return result;
	}
	
	/**
	 * オプションサービス契約一覧照会(CSコース)を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼出
	 * @param param パラメーター
	 * @param dataMapKey データマップキー
	 * @param opSvcCd オプションサービスコード
	 * @param cascdNo CASカード番号
	 * @param pcrsCd 料金コースコード
	 * @return CAANMsg[]
	 * @throws Throwable
	 */
	private CAANMsg[] execEKK0351B016(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String opSvcCd,
									String cascdNo,
									String pcrsCd) throws Throwable
	{
		
		Object[][] ekk0351b016In =
		{
				{EKK0351B016CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0351B016},
				{EKK0351B016CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
				{EKK0351B016CBSMsg.KEY_OP_SVC_CD, opSvcCd},
				{EKK0351B016CBSMsg.KEY_CASCD_NO, cascdNo},
				{EKK0351B016CBSMsg.KEY_PCRS_CD, pcrsCd},
		};
		
		CAANMsg ekk0351b016Msg = callSC(handle, scCall, param, dataMapKey, ekk0351b016In);
		
		CAANMsg[] ekk0351b016MsgList = ekk0351b016Msg.getCAANMsgList(EKK0351B016CBSMsg.EKK0351B016CBSMSG1LIST);
		
		return ekk0351b016MsgList;
	}
	
	/**
	 * CAS番号対象オプションサービス契約登録を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼び出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey データマップキー
	 * @param funcCd 機能コード
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param cascdNo CASカード番号
	 * @param sptvRnkStat スカパー連携ステータス
	 * @param keyopnYmd 鍵開け年月日
	 * @param keyclsYmd 鍵閉め年月日
	 * @param casNoTgAplyYmd CAS番号対象適用年月日
	 * @param keyclsRsnCd 鍵閉め理由コード
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK3561D010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String funcCd,
									String opSvcKeiNo,
									String cascdNo,
									String sptvRnkStat,
									String keyopnYmd,
									String keyclsYmd,
									String casNoTgAplyYmd,
									String keyclsRsnCd) throws Throwable
	{
		Object[][] ekk3561d010In =
		{
				{EKK3561D010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK3561D010},
				{EKK3561D010CBSMsg.FUNC_CODE, funcCd},
				{EKK3561D010CBSMsg.OP_SVC_KEI_NO, opSvcKeiNo},
				{EKK3561D010CBSMsg.CASCD_NO, cascdNo},
				{EKK3561D010CBSMsg.SPTV_RNK_STAT, sptvRnkStat},
				{EKK3561D010CBSMsg.KEYOPN_YMD, keyopnYmd},
				{EKK3561D010CBSMsg.KEYCLS_YMD, keyclsYmd},
				{EKK3561D010CBSMsg.CAS_NO_TG_APLY_YMD, casNoTgAplyYmd},
				{EKK3561D010CBSMsg.KEYCLS_RSN_CD, keyclsRsnCd},
		};
		
		return callSC(handle, scCall, param, dataMapKey, ekk3561d010In);
	}
	
	/**
	 * CAS番号対象オプションサービス契約変更を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼び出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey データマップキー
	 * @param funcCd 機能コード
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param cascdNo CASカード番号
	 * @param sptvRnkStat スカパー連携ステータス
	 * @param keyopnYmd 鍵開け年月日
	 * @param keyclsYmd 鍵閉め年月日
	 * @param casNoTgAplyYmd CAS番号対象適用年月日
	 * @param keyclsRsnCd 鍵閉め理由コード
	 * @param updDtmBf 更新年月日時分秒(更新前)
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK3561C010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String funcCd,
									String opSvcKeiNo,
									String cascdNo,
									String sptvRnkStat,
									String keyopnYmd,
									String keyclsYmd,
									String casNoTgAplyYmd,
									String keyclsRsnCd,
									String updDtmBf) throws Throwable
	{
		Object[][] ekk3561c010In =
		{
				{EKK3561C010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK3561C010},
				{EKK3561C010CBSMsg.FUNC_CODE, funcCd},
				{EKK3561C010CBSMsg.OP_SVC_KEI_NO, opSvcKeiNo},
				{EKK3561C010CBSMsg.CASCD_NO, cascdNo},
				{EKK3561C010CBSMsg.SPTV_RNK_STAT, sptvRnkStat},
				{EKK3561C010CBSMsg.KEYOPN_YMD, keyopnYmd},
				{EKK3561C010CBSMsg.KEYCLS_YMD, keyclsYmd},
				{EKK3561C010CBSMsg.CAS_NO_TG_APLY_YMD, casNoTgAplyYmd},
				{EKK3561C010CBSMsg.KEYCLS_RSN_CD, keyclsRsnCd},
				{EKK3561C010CBSMsg.UPD_DTM_BF, updDtmBf},
		};
		
		return callSC(handle, scCall, param, dataMapKey, ekk3561c010In);
	}
	
	/**
	 * CAS番号対象オプションサービス契約物理削除を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼び出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey データマップキー
	 * @param funcCd 機能コード
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param updDtmBf 更新年月日時分秒(更新前)
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK3561E010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String funcCd,
									String opSvcKeiNo,
									String updDtmBf) throws Throwable
	{
		Object[][] ekk3561e010In =
		{
				{EKK3561E010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK3561E010},
				{EKK3561E010CBSMsg.FUNC_CODE, funcCd},
				{EKK3561E010CBSMsg.OP_SVC_KEI_NO, opSvcKeiNo},
				{EKK3561E010CBSMsg.UPD_DTM_BF, updDtmBf},
		};
		
		return callSC(handle, scCall, param, dataMapKey, ekk3561e010In);
	}
	
	/**
	 * CAS番号対象オプションサービス契約履歴登録を行う。
	 * @param handle セッションハンドル
	 * @param scCall SC呼び出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey データマップキー
	 * @param funcCd 機能コード
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param rkAddDtm 履歴登録年月日時分秒
	 * @param cascdNo CASカード番号
	 * @param sptvRnkStat スカパー連携ステータス
	 * @param keyopnYmd 鍵開け年月日
	 * @param keyclsYmd 鍵閉め年月日
	 * @param casNoTgAplyYmd CAS番号対象適用年月日
	 * @param keyclsRsnCd 鍵閉め理由コード
	 * @return CAANMsg
	 * @throws Throwable
	 */
	private CAANMsg execEKK3571D010(SessionHandle handle,
									ServiceComponentRequestInvoker scCall,
									IRequestParameterReadWrite param,
									String dataMapKey,
									String funcCd,
									String opSvcKeiNo,
									String rkAddDtm,
									String cascdNo,
									String sptvRnkStat,
									String keyopnYmd,
									String keyclsYmd,
									String casNoTgAplyYmd,
									String keyclsRsnCd) throws Throwable
	{
		Object[][] ekk3571d010In =
		{
				{EKK3571D010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK3571D010},
				{EKK3571D010CBSMsg.FUNC_CODE, funcCd},
				{EKK3571D010CBSMsg.OP_SVC_KEI_NO, opSvcKeiNo},
				{EKK3571D010CBSMsg.RK_ADD_DTM, rkAddDtm},
				{EKK3571D010CBSMsg.CASCD_NO, cascdNo},
				{EKK3571D010CBSMsg.SPTV_RNK_STAT, sptvRnkStat},
				{EKK3571D010CBSMsg.KEYOPN_YMD, keyopnYmd},
				{EKK3571D010CBSMsg.KEYCLS_YMD, keyclsYmd},
				{EKK3571D010CBSMsg.CAS_NO_TG_APLY_YMD, casNoTgAplyYmd},
				{EKK3571D010CBSMsg.KEYCLS_RSN_CD, keyclsRsnCd},
		};
		
		return callSC(handle, scCall, param, dataMapKey, ekk3571d010In);
	}
	
	/**
	 * @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));
		
		String svcIf = (String)mappingData[0][1];
		
		CAANMsg template = new CAANMsg(String.format("eo.ejb.cbs.cbsmsg.%sCBSMsg", svcIf));

		// オペレータ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++)
		{
			/* CAANMsg[]の場合 */
			if (mappingData[i][1] instanceof CAANMsg[])
			{
				 template.set((String)mappingData[i][0], (CAANMsg[])mappingData[i][1]);
			}
			/* CAANMsg[]の以外 */
			else
			{
				/* nullの場合*/
				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
	 * @param mappingData
	 * @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);
		
		/* 0以外のとき */
		if (returnCode != 0)
		{
			templateStatus = 9000;
		}
		
		/* nullのとき */
		if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", templateStatus)) == null)
		{
			templateStatus = 0;
		}

		int bpStatus = 0;
		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		/* nullの場合 */
		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++)
		{
			/* nullチェック　*/
			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;
	}
	
	/**
	 * 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);
		int 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;
	}
}
