/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCNContUseStaCreCC
*   ソースファイル名：JCNContUseStaCreCC.java
*   作成者          ：富士通
*   日付            ：2021年05月14日
*＜機能概要＞
*   eoモバイル登録チェックを行います。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
* v53.00.00       2021/05/13  FJ)加藤      ANK-4009-00-00_CX戦略WG方針対応
* v53.00.01       2021/06/14  FJ)星野      IT1-2021-000XXXX
* v54.00.00       2021/07/21  FJ)杉本      ANK-4092-00-00_CX戦略WG方針対応STEP2
* v65.00.00       2023/10/10  FJ)北村      ANK-4346-00-00_【eo定期】CCMG再構築対応
* v73.00.00       2024/12/11  FJ)謝       【ANK-4570-00-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 java.util.Iterator;
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.ICommonComponent;
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.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JCNStringUtil;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg3List;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg4List;
import eo.ejb.cbs.cbsmsg.ECNA0140001CBSMsg5List;
import eo.ejb.cbs.cbsmsg.ECNA0150001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0150001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0160001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0160001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0160001CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECNA0190001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0190001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0200001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0200001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg3List;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg4List;
import eo.ejb.cbs.cbsmsg.ECNA0250001CBSMsg5List;
import eo.ejb.cbs.cbsmsg.ECNA0260001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECNA0260001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECNA0260001CBSMsg2List;


/**
 * コンテンツ利用開始登録を行う。
 * <BR>
 * @author 富士通
 */
public class JCNContUseStaCreCC extends AbstractCommonComponent implements ICommonComponent
{
	/** サービスコンポーネントエラー発生時のエラー文字列 */
	private static final String SC_ERROR_STRING = "サービスコンポーネントエラー";

	/** テンプレートID：会員利用認証 */
	private static final String TEMPLATE_ID_ECNA0140001 = "ECNA0140001";
	/** テンプレートID：契約可能コンテンツ照会 */
	private static final String TEMPLATE_ID_ECNA0150001 = "ECNA0150001";
	/** テンプレートID：コンテンツ契約登録 */
	private static final String TEMPLATE_ID_ECNA0160001 = "ECNA0160001";

// ANK-4346-00-00 ADD START
	/** テンプレートID：コンテンツ処理番号発行 */
	private static final String TEMPLATE_ID_ECNA0190001 = "ECNA0190001";
	/** テンプレートID：契約可能コンテンツ取得 */
	private static final String TEMPLATE_ID_ECNA0250001 = "ECNA0250001";
	/** テンプレートID：コンテンツ即時契約 */
	private static final String TEMPLATE_ID_ECNA0260001 = "ECNA0260001";

	/** 作業用マップのキー：処理番号  */
	private static final String WORK_MAP_KEY_OPERATION_ID = "operationId";
	/** CC出力パラメータ：処理結果コード */
	public static final String RETURN_CODE = "return_code";
	/** CC出力パラメータ：エラー機能識別コード */
	public static final String ERR_SKBT_CODE = "err_skbt_code";
	/** リターンコード 正常値 */
	private static final String RETURN_CODE_OK = "00000";
	/** エラー機能識別コード 0（エラーなし） */
	private static final String ERR_SKBT_CD_0 = "0";
	/** エラー機能識別コード 1（処理番号発行） */
	private static final String ERR_SKBT_CD_1 = "1";
// ANK-4346-00-00 ADD END
// ANK-4570-00-00 ADD START
	/** エラー機能識別コード 2（コンテンツ即時契約） */
	private static final String ERR_SKBT_CD_2 = "2";
	/** エラー機能識別コード 3（契約可能コンテンツ取得） */
	private static final String ERR_SKBT_CD_3 = "3";
	/** CC出力パラメータ：出力エラー機能識別コード */
	public static final String OUT_ERR_SKBT_CD = "out_err_skbt_cd";
	/** CC出力パラメータ：出力エラーコード */
	public static final String OUT_ERR_CD = "out_err_cd";
// ANK-4570-00-00 ADD END

	/** リターンメッセージ取得キー */
	private static final String RETURN_MESSAGE_STRING = "RETURN_MESSAGE_";
	/** リターンメッセージの書式指定文字列 */
	private static final String RETURN_MESSAGE_FORMAT = "%1$04d";
	/** エラー項目接尾辞 */
	private static final String ERRITEM_SUFFIX = "_err";


	
	/** 作業用マップのキー：利用認証ID  */
	private static final String WORK_MAP_KEY_USE_CERTIFY_ID = "useCertifyId";
	
	/**
	 * コンテンツ利用開始登録をします。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @return リクエストパラメータ
	 * @throws Throwable 例外が発生した場合
	 */
	public IRequestParameterReadWrite Main(SessionHandle handle, 
													IRequestParameterReadWrite param, 
													String fixedText) throws Throwable
	{
		try{
			// 開始ログ
			outDebugLog("----- IRequestParameterReadWrite Start  -----");
			
			// 契約者情報登録マップ
// ANK-4436-00-00 MOD START
			//Map<String, Object> ccMsg = (Map<String, Object>)param.getData(fixedText);
			HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(fixedText);
// ANK-4436-00-00 MOD END
			
			// 作業用マップ
			Map<String, String> work = new HashMap<String, String>();
			
// ANK-4436-00-00 MOD START
			// 契約可能コンテンツ照会(廃止)
			//ContReff(handle, param, fixedText, ccMsg, work);

			// 会員利用認証(廃止)
			//KaiinNinsho(handle, param, fixedText, ccMsg, work);

			// コンテンツ契約登録(廃止)
			//addRrks(handle, param, fixedText, ccMsg, work);

			// 契約可能コンテンツ照会
			contractableContentsReff(handle, param, fixedText, ccMsg, work);

			// 処理番号発行
			getOperationId(handle, param, fixedText, ccMsg, work);

			// コンテンツ契約登録
			addContentsSokujiKeiyaku(handle, param, fixedText, ccMsg, work);
// ANK-4436-00-00 MOD END
			// レスポンス項目設定
			setResponse(ccMsg, work);
			
			// 終了ログ
			outDebugLog("----- IRequestParameterReadWrite End  -----");

			return param;
		}
		catch(Exception e)
		{
// ANK-4570-00-00 ADD START
			if ("CNSV006601CC".equals(fixedText))
			{
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				return param;
			}
// ANK-4570-00-00 ADD END
			// エラーログ
			outDebugLog("----- IRequestParameterReadWrite Err  -----");
			throw e;
		}
	}
	/**
	 * 契約可能コンテンツを照会します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void ContReff(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, Map<String, Object> ccMsg,
			Map<String, String> work)
	throws Throwable
	{
		// 照会結果情報
		CAANMsg reffResultMsg = null;
		
		//値の設定
		//契約種別
		String contractClass = "1,4";
		//申込チャネル
		String applicationChannel = "1";
		
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// 契約可能コンテンツ照会の上りマッピング
		Object[][] ecna0140001In =
		{
			{ECNA0140001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0140001}
			// 機能コード
			,{ECNA0140001CBSMsg.FUNC_CODE, "1"}
			// SYSID
			,{ECNA0140001CBSMsg.KEY_SYS_ID, (String)ccMsg.get("sysid")}
			// コンテンツサービスID
// IT1-2021-000XXXX対応 20210614 星野 MOD START
//			,{ECNA0140001CBSMsg.KEY_SERVICE_ID, (String)ccMsg.get("cont_cd")}
			,{ECNA0140001CBSMsg.KEY_SERVICE_ID, (String)ccMsg.get("cont_svc_cd")}
// IT1-2021-000XXXX対応 20210614 星野 MOD END
			// 契約種別
			,{ECNA0140001CBSMsg.KEY_CONTRACT_CLASS, contractClass}
			// 申込チャネル
			,{ECNA0140001CBSMsg.KEY_APPLICATION_CHANNEL, applicationChannel}
		};

		// サービスIF実行
		reffResultMsg = callSC(handle, scCall, param, fixedText, ecna0140001In);
		// リターンコードチェック
		checkReturnCode(param);
	}
	
	
	/**
	 * 会員利用を認証します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void KaiinNinsho(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, Map<String, Object> ccMsg,
			Map<String, String> work)
	throws Throwable
	{
		// 認証結果情報
		CAANMsg ninshoResultMsg = null;
		
		// 認証された利用認証ID
		String useCertifyId = "";
		
		//値の設定
		//有効期限
		String contractClass = "10";
		
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// 会員利用の上りマッピング
		Object[][] ecna0150001In =
		{
			{ECNA0150001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0150001}
			// 機能コード
			,{ECNA0150001CBSMsg.FUNC_CODE, "1"}
			// コンテンツサービスID
			,{ECNA0150001CBSMsg.SERVICE_ID, (String)ccMsg.get("cont_svc_cd")}
			// SYSID
			,{ECNA0150001CBSMsg.SYS_ID, (String)ccMsg.get("sysid")}
			// 有効期限
			,{ECNA0150001CBSMsg.AVAILABLE_TIME, contractClass}
		};
		
		
		// サービスIF実行
		ninshoResultMsg = callSC(handle, scCall, param, fixedText, ecna0150001In);
		// リターンコードチェック
		checkReturnCode(param);
		
		// 認証された利用認証IDを取得
		useCertifyId = ninshoResultMsg.getString(ECNA0150001CBSMsg.USE_CERTIFY_ID);
		// 作業用マップに設定
		work.put(WORK_MAP_KEY_USE_CERTIFY_ID, useCertifyId);
	}
	
	/**
	 * レスポンス項目を設定します。
	 * <br>
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 */
	private void setResponse(Map<String, Object> ccMsg, Map<String, String> work)
	{
		// コンテンツサービスコード
		ccMsg.put("cont_svc_cd", (String)ccMsg.get("cont_svc_cd"));
	}
	
	/**
	 * コンテンツ契約を登録します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void addRrks(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, Map<String, Object> ccMsg,
			Map<String, String> work)
	throws Throwable
	{
		// 登録結果情報
		CAANMsg addResultMsg = null;
		
		// 認証された利用認証IDを取得
		String useCertifyId = work.get(WORK_MAP_KEY_USE_CERTIFY_ID);
		
		//値の設定
		//契約数量
		String targetContractAmount = "1";
		//決済方法番号
		String settlementWayNo = "1";
		//申込チャネル
		String applicationChannel = "1";
		//コンテンツID
		String contentsId = (String)ccMsg.get("cont_svc_cd") + (String)ccMsg.get("cont_cd");
		
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// コンテンツ契約の上りマッピング
		Object[][] ecna0160001In =
		{
			{ECNA0160001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0160001}
			// 機能コード
			,{ECNA0160001CBSMsg.FUNC_CODE, "1"}
			// コンテンツサービスID
			,{ECNA0160001CBSMsg.SERVICE_ID, (String)ccMsg.get("cont_svc_cd")}
			// 利用認証ID
			,{ECNA0160001CBSMsg.USE_CERTIFY_ID, useCertifyId}
			// コンテンツID
			,{ECNA0160001CBSMsg.TARGET_CONTENTS_ID, contentsId}
			// 契約数量
			,{ECNA0160001CBSMsg.TARGET_CONTRACT_AMOUNT, targetContractAmount}
			// 決済方法番号
			,{ECNA0160001CBSMsg.SETTLEMENT_WAY_NO, settlementWayNo}
			// クレジットカードID
			,{ECNA0160001CBSMsg.CREDIT_ID, (String)ccMsg.get("payway_id")}
			// 申込チャネル
			,{ECNA0160001CBSMsg.APPLICATION_CHANNEL, applicationChannel}
			// ANK-4092-00-00 20210721 ADD START
			// キャンペーンコード
			,{ECNA0160001CBSMsg.CAMPAIGN_CD, (String)ccMsg.get("cont_cmp_cd")}
			// ANK-4092-00-00 20210721 ADD END
		};

		// サービスIF実行
		addResultMsg = callSC(handle, scCall, param, fixedText, ecna0160001In);
		// リターンコードチェック
		checkReturnCode(param);
	}
	

	/**
	 * SC(サービスインターフェイス）を呼び出します。
	 * @param handle セッションハンドル
	 * @param scCall SC呼び出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey パラメータキー
	 * @param mappingData マッピングデータ
	 * @return サービスインターフェイス実行結果
	 * @throws Throwable 例外が発生した場合
	 */
	private CAANMsg callSC(SessionHandle handle, 
							ServiceComponentRequestInvoker scCall, 
							IRequestParameterReadWrite param, 
							String dataMapKey,
							Object[][] mappingData)
	throws Throwable
	{
		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);
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		
		if (null == errList)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(result, errList));
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if (!("0".equals(RETURN_CODE.toString()) && 0 == status))
		{
// ANK-4570-00-00 ADD START
			if ("CNSV006601CC".equals(dataMapKey))
			{
				// ユーザデータ情報
				HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(dataMapKey);
				
				// コンテンツ処理番号発行
				if (TEMPLATE_ID_ECNA0190001.equals(msg.getString(JCMConstants.TEMPLATE_ID_KEY)))
				{
					// エラー機能識別コード
					ccMsg.put(OUT_ERR_SKBT_CD, ERR_SKBT_CD_1);
					// エラーコード
					String errCd = "";
					// 処理番号発行 処理番号発行情報明細
					CAANMsg[] ecna0190001Msg1List = msg.getCAANMsgList(ECNA0190001CBSMsg.ECNA0190001CBSMSG1LIST);
					
					// 結果が取得できていれば取得する。
					if (ecna0190001Msg1List != null && ecna0190001Msg1List.length > 0)
					{
						errCd = ecna0190001Msg1List[0].getString(ECNA0190001CBSMsg1List.ERR_CD);
					}
					ccMsg.put(OUT_ERR_CD, errCd);
				}
				// 契約可能コンテンツ取得
				else if (TEMPLATE_ID_ECNA0250001.equals(msg.getString(JCMConstants.TEMPLATE_ID_KEY)))
				{
					// エラー機能識別コード
					ccMsg.put(OUT_ERR_SKBT_CD, ERR_SKBT_CD_3);
					// エラーコード
					ccMsg.put(OUT_ERR_CD, msg.getString(ECNA0250001CBSMsg.ERR_CD));
				}
				// コンテンツ即時契約
				else if (TEMPLATE_ID_ECNA0260001.equals(msg.getString(JCMConstants.TEMPLATE_ID_KEY)))
				{
					// エラー機能識別コード
					ccMsg.put(OUT_ERR_SKBT_CD, ERR_SKBT_CD_2);
					// エラーコード
					ccMsg.put(OUT_ERR_CD, msg.getString(ECNA0260001CBSMsg.ERR_CD));
				}
			}
// ANK-4570-00-00 ADD END
			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));

		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++)
		{
			if (mappingData[i][1] instanceof CAANMsg[])
			{
				 template.set((String)mappingData[i][0], (CAANMsg[])mappingData[i][1]);
			}
			else
			{
				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 CAANMsgクラス
	 * @param returnCode リターンコード
	 * @param dataMapKey パラメータキー
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException リクエストパラメータの操作でエラーが発生した場合
	 */
	private IRequestParameterReadWrite editErrorInfoCom(IRequestParameterReadWrite param,
														CAANMsg[] templates, 
														int returnCode,
														String dataMapKey) throws RequestParameterException
	{
		CAANMsg template = templates[0];

		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (0 != returnCode)
		{
			templateStatus = 9000;
		}

		if (null == JCMAPLConstMgr.getString(RETURN_MESSAGE_STRING + String.format(RETURN_MESSAGE_FORMAT, templateStatus)))
		{
			templateStatus = 0;
		}

		int bpStatus = 0;

		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		
		if (null == obj)
		{
			bpStatus = -1;
		}
		else
		{
			bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
		}

		if (templateStatus > bpStatus)
		{
			// BPにサービスコンポーネントのステータスを設定する。
			String formatStatus = String.format(RETURN_MESSAGE_FORMAT, templateStatus);
			
			String message = JCMAPLConstMgr.getString(RETURN_MESSAGE_STRING + formatStatus);
			
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}

		// ユーザデータ情報
		HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(dataMapKey);

		HashMap map = template.getHashMap();
		Iterator it = map.keySet().iterator();
		while (it.hasNext())
		{
			String key = (String)it.next();
			Object value = map.get(key);
			if (value instanceof HashMap[])
			{
				HashMap[] childMapList = (HashMap[])value;
				for (HashMap childMap : childMapList)
				{
					Iterator childIt = childMap.keySet().iterator();
					while (childIt.hasNext())
					{
						String childKey = (String)childIt.next();
						if (childKey.endsWith(ERRITEM_SUFFIX))
						{
							int keyIdx = childKey.lastIndexOf(ERRITEM_SUFFIX);
							if (inMap.containsKey(childKey.substring(0, keyIdx)))
							{
								inMap.put(childKey, childMap.get(childKey));
							}
						}
					}
				}
			}
			else
			{
				if (key.endsWith(ERRITEM_SUFFIX))
				{
					int keyIdx = key.lastIndexOf(ERRITEM_SUFFIX);
					if (inMap.containsKey(key.substring(0, keyIdx)))
					{
						inMap.put(key, map.get(key));
					}
				}
			}
		}

		return param;
	}

	/**
	 * SCのリターンコードを取得します。
	 * <br>
	 * @param param リクエストパラメータ
	 * @return SCの実行ステータス
	 * @throws Exception 例外が発生した場合
	 */
	private int getReturnCode(IRequestParameterReadWrite param) throws Exception
	{
		return Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
	}

	/**
	 * SCのリターンコードを判定し、エラーであれば例外を送出します。
	 * @param param リクエストパラメータ
	 * @throws Exception 例外が発生した場合
	 * @throws CCException 単項目エラー以上のエラーが発生した場合
	 */
	private void checkReturnCode(IRequestParameterReadWrite param)
	throws Exception, CCException
	{
		if (getReturnCode(param) >= JPCModelConstant.SINGLEDATA_ERR)
		{
			// ステータスが単項目エラー以上であれば例外をスロー
			throw new CCException(SC_ERROR_STRING, new Exception());
		}
	}
	

	/**
	 * デバッグ出力処理です。
	 * 
	 * <br>
	 * @param obj 出力内容
	 */
	private void outDebugLog(Object obj)
	{
		// デバッグ出力
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), obj, null, null, null);
	}

// ANK-4346-00-00 MOD START
	/**
	 * 契約可能コンテンツを照会します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void contractableContentsReff(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, Map<String, Object> ccMsg,
			Map<String, String> work)
	throws Throwable
	{
		// 照会結果情報
		CAANMsg reffResultMsg = null;
		//値の設定
		//契約種別
		String contractClass = "1,4";
		//申込チャネル
		String applicationChannel = "1";
		
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// 契約可能コンテンツ照会の上りマッピング
		Object[][] ecna0250001In =
		{
			{ECNA0250001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0250001}
			// 機能コード
			,{ECNA0250001CBSMsg.FUNC_CODE, "1"}
			// SYSID
			,{ECNA0250001CBSMsg.KEY_SYSID, (String)ccMsg.get("sysid")}
			// コンテンツサービスID
			,{ECNA0250001CBSMsg.KEY_SERVICE_ID, (String)ccMsg.get("cont_svc_cd")}
			// 契約種別
			,{ECNA0250001CBSMsg.KEY_CONTRACT_CLASS, contractClass}
			// 申込チャネル
			,{ECNA0250001CBSMsg.KEY_APPLICATION_CHANNEL, applicationChannel}
		};

		// サービスIF実行
		reffResultMsg = callSC(handle, scCall, param, fixedText, ecna0250001In);
		// リターンコードチェック
		checkReturnCode(param);
	}
	
	
	/**
	 * 処理番号発行APIを実行します。
	 * <br> 
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void getOperationId(SessionHandle handle, IRequestParameterReadWrite param, String fixedText
			, HashMap<String, Object> ccMsg,
			Map<String, String> work)
	throws Throwable
	{
		/*******************/
		/** 処理番号発行 **/
		/******************/
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		
		Object[][] ecna0190001in = editShoriNmberHakkoInMsg(ccMsg);
		
		// サービスIF実行
		// 処理番号発行明細
		CAANMsg ecna0190001CBSMsg = callSC(handle, scCall, param, fixedText, ecna0190001in);
		
		// 処理番号発行 処理番号発行情報明細
		CAANMsg[] ecna0190001Msg1List = ecna0190001CBSMsg.getCAANMsgList(ECNA0190001CBSMsg.ECNA0190001CBSMSG1LIST);

		String operationId = null;
		
		// 結果が取得できていれば取得する。
		if (ecna0190001Msg1List != null && ecna0190001Msg1List.length > 0)
		{
			CAANMsg ecna0019001Msg1ListMap = ecna0190001Msg1List[0];
			
			operationId = ecna0019001Msg1ListMap.getString(ECNA0190001CBSMsg1List.OPERATION_ID);
			// API実行結果の取得
			String errCd = ecna0019001Msg1ListMap.getString(ECNA0190001CBSMsg1List.ERR_CD);
			
			// リターンコードが正常終了以外の場合、後続処理を実施しない。
			if ( !RETURN_CODE_OK.equals(errCd) )
			{
				// エラー識別コードに "1":処理番号発行でのエラー を設定
				ccMsg.put(ERR_SKBT_CODE , ERR_SKBT_CD_1);
				ccMsg.put(RETURN_CODE , errCd);
				return ;
			}
			// 作業用マップに設定
			work.put(WORK_MAP_KEY_OPERATION_ID, operationId);
		}
	}

	/**
	 * コンテンツ即時契約を呼出、コンテンツ契約を登録します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg 契約者情報登録マップ
	 * @param work 作業用マップ
	 * @throws Throwable 例外が発生した場合
	 */
	private void addContentsSokujiKeiyaku(SessionHandle handle, IRequestParameterReadWrite param
			, String fixedText, HashMap<String, Object> ccMsg, Map<String, String> work)
	throws Throwable
	{
		// 登録結果情報
		CAANMsg addResultMsg = null;
		//決済方法番号
		String settlementWayNo = "1";
		//申込チャネル
		String applicationChannel = "1";
		//コンテンツID
		String contentsId = (String)ccMsg.get("cont_svc_cd") + (String)ccMsg.get("cont_cd");
		
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

// ANK-4570-00-00 ADD START
		if (!JCNStringUtil.isNullBlank((String)ccMsg.get("settlement_way_no")))
		{
			settlementWayNo = (String)ccMsg.get("settlement_way_no");
		}
// ANK-4570-00-00 ADD END

		/**********************/
		/**コンテンツ即時契約**/
		/**********************/
		// 発行された処理番号を取得
		String operationId = work.get(WORK_MAP_KEY_OPERATION_ID);

		// コンテンツ配列の設定
		StringBuilder contents_aryList = new StringBuilder();
		contents_aryList.append("contents_id" + ",");
		contents_aryList.append(contentsId);
// ANK-4570-00-00 ADD START
		if (!JCNStringUtil.isNullBlank((String)ccMsg.get("cont_cmp_cd")))
		{
			contents_aryList.append("," + "campaign_cd" + ",");
			contents_aryList.append((String)ccMsg.get("cont_cmp_cd"));
		}
// ANK-4570-00-00 ADD END
		
		// コンテンツ契約の上りマッピング
		Object[][] ecna0260001In =
		{
			{ECNA0260001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0260001}
			// 機能コード
			,{ECNA0260001CBSMsg.FUNC_CODE, "1"}
			// SYSID
			,{ECNA0260001CBSMsg.KEY_SYSID, (String)ccMsg.get("sysid")}
			// コンテンツサービスID
			,{ECNA0260001CBSMsg.KEY_SERVICE_ID, (String)ccMsg.get("cont_svc_cd")}
			// コンテンツ配列
			,{ECNA0260001CBSMsg.ECNA0260001CBSMSG1LIST, contents_aryList.toString()}
			// 処理番号
			,{ECNA0260001CBSMsg.KEY_OPERATION_ID, operationId}
			// 決済方法番号
			,{ECNA0260001CBSMsg.KEY_SETTLEMENT_WAY_NO, settlementWayNo}
			// クレジットカードID
			,{ECNA0260001CBSMsg.KEY_CREDIT_ID, (String)ccMsg.get("payway_id")}
			// 申込チャネル
			,{ECNA0260001CBSMsg.KEY_APPLICATION_CHANNEL, applicationChannel}
// ANK-4570-00-00 ADD START
			// 申込日時
			,{ECNA0260001CBSMsg.KEY_APPLICATION_DATE, (String)ccMsg.get("application_date")}
// ANK-4570-00-00 ADD END
		};
		
		// サービスIF実行
		// コンテンツ即時契約
		CAANMsg ecna0260001CBSMsg = callSC(handle, scCall, param, fixedText, ecna0260001In);

		String errCd = ecna0260001CBSMsg.getString(ECNA0260001CBSMsg.ERR_CD);
		// リターンコードが正常終了以外の場合、後続処理を実施しない。
		if ( !RETURN_CODE_OK.equals(errCd) )
		{
			// エラー識別コードに "2":料金訂正登録・変更でのエラー を設定
			ccMsg.put(ERR_SKBT_CODE , ERR_SKBT_CODE);
			ccMsg.put(RETURN_CODE , errCd);
			return ;
		}
	}

	private Object[][] editShoriNmberHakkoInMsg(HashMap<String, Object> ccMsg) {
		
		Object[][] ecna0190001in = 
		{
			  {ECNA0190001CBSMsg.TEMPLATEID, TEMPLATE_ID_ECNA0190001}				// テンプレートＩＤ
			, {ECNA0190001CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1}				// 機能コード
			
		};
		
		return ecna0190001in;
	}
// ANK-4346-00-00 MOD END
}
