/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKSmtvlYoSanshoKeiInfCC
*	ソースファイル名：JKKSmtvlYoSanshoKeiInfCC.java
*	作成者			：富士通
*	日付			：2012年10月08日
*＜機能概要＞
*	スマートバリュー用参照_契約情報CC
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v4.00.00	2012/10/08	FJ)強矢		新規作成 【ANK-0534-00-00】WDAスマートバリュー対応
*	v5.00.00	2013/02/01	FJ)神田		【ANK-1402-00-00】法人のお客様名設定見直し対応
*	v7.00.00	2014/03/11	FJ)澁谷		【OM-2014-0001029】申込書番号の取得方法見直し対応
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.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 eo.common.util.JZMAdOutputEdit;
import eo.ejb.cbs.cbsmsg.ECK0011A010CBSMsg;
import eo.ejb.cbs.cbsmsg.ECK0011A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECK0201B030CBSMsg;
import eo.ejb.cbs.cbsmsg.ECK0201B030CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0021A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0021A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0081B024CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081B024CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0241B002CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0241B003CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0241B003CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0251A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0251A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0451A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0481B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0481B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0841A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0841A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2141B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2141B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0011A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKU0011A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0081B010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKU0081B010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0091B020CBSMsg;
import eo.ejb.cbs.cbsmsg.EKU0091B020CBSMsg1List;


/**
 * スマートバリュー用参照の契約情報の取得を行う部品。
 * 
 * @author 富士通
 *
 */
public class JKKSmtvlYoSanshoKeiInfCC extends AbstractCommonComponent
{

	/** テンプレートID(EKK0081A010) */
	private static final String TEMPLATE_ID_EKK0081A010 = "EKK0081A010";
	
	/** テンプレートID(ECK0011A010) */
	private static final String TEMPLATE_ID_ECK0011A010 = "ECK0011A010";
	
	/** テンプレートID(ECK0201B030) */
	private static final String TEMPLATE_ID_ECK0201B030 = "ECK0201B030";
	
	/** テンプレートID(EKK0241B003) */
	private static final String TEMPLATE_ID_EKK0241B003 = "EKK0241B003";
	
	/** テンプレートID(EKK0251A010) */
	private static final String TEMPLATE_ID_EKK0251A010 = "EKK0251A010";
	
	/** テンプレートID(EKK0241B002) */
	private static final String TEMPLATE_ID_EKK0241B002 = "EKK0241B002";
	
	/** テンプレートID(EKK0481B001) */
	private static final String TEMPLATE_ID_EKK0481B001 = "EKK0481B001";
	
	/** テンプレートID(EKK0451A010) */
	private static final String TEMPLATE_ID_EKK0451A010 = "EKK0451A010";
	
	/** テンプレートID(EKK0841A010) */
	private static final String TEMPLATE_ID_EKK0841A010 = "EKK0841A010";
	
	/** テンプレートID(EKK2141B001) */
	private static final String TEMPLATE_ID_EKK2141B001 = "EKK2141B001";
	
	/** テンプレートID(EKU0081B010) */
	private static final String TEMPLATE_ID_EKU0081B010 = "EKU0081B010";
	
	/** テンプレートID(EKU0081B010) */
	private static final String TEMPLATE_ID_EKU0011A010 = "EKU0011A010";
	
	/** テンプレートID(EKU0091B020) */
	private static final String TEMPLATE_ID_EKU0091B020 = "EKU0091B020";
	
	/** テンプレートID(EKK0081B024) */
	private static final String TEMPLATE_ID_EKK0081B024 = "EKK0081B024";
	
	/** テンプレートID(EKK0021A010) */
	private static final String TEMPLATE_ID_EKK0021A010 = "EKK0021A010";
	
	/** サービスID */
	private static final String SERVICE_ID = "KKSV065101CC";
	
	
	/**
	 * スマートバリュー用参照の契約情報の取得を行う。
	 * 
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return IRequestParameterReadWrite リクエストパラメータ
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite getSmtvlYoSanshoKeiInf(SessionHandle handle, 
															IRequestParameterReadWrite param, 
															String fixedText) throws Exception
	{
		HashMap<String, Object> work02Map = new HashMap<String, Object>();
		param.setData("KKSV0651WORK02", work02Map);
		
		// ◇ SC呼出実行
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない）
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(SERVICE_ID);
		
		// ***** EKK0081A010(サービス契約一意照会) の実行 *****
		Object[][] ekk0081a010IN = {
				// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
				{EKK0081A010CBSMsg.KEY_SVC_KEI_NO, (String)ccMsg.get("key_svc_kei_no")},
				// "" => ＫＥＹ＿世代登録年月日時分秒
				{EKK0081A010CBSMsg.KEY_GENE_ADD_DTM, ""},
				// 運用日 => ＫＥＹ＿予約適用年月日
				{EKK0081A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null)}
		};
		
		// ◇ SC呼出実行
		CAANMsg ekk0081a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0081A010, "2", ekk0081a010IN);
		
		// 処理結果
		CAANMsg[] ekk0081a010MsgList = ekk0081a010Msg.getCAANMsgList(EKK0081A010CBSMsg.EKK0081A010CBSMSG1LIST);
		
		// サービス契約一意照会の検索結果が無い場合
		if (ekk0081a010MsgList == null || ekk0081a010MsgList.length == 0)
		{
			work02Map.put("return_result_cd", "000000");
			return param;
		}
		else
		{
			String svc_kei_stat = ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.SVC_KEI_STAT);
			
			// サービス契約ステータスが "020"(照査済) "030"(締結済) "100"(サービス提供中) "210"(休止・中断中) "220"(停止中)以外は対象データとしない。
			ArrayList<String> conditionList = new ArrayList<String>();
			conditionList.add("020");
			conditionList.add("030");
			conditionList.add("100");
			conditionList.add("210");
			conditionList.add("220");
			
			if (!conditionList.contains(svc_kei_stat))
			{
				work02Map.put("return_result_cd", "000000");
				return param;
			}
		}
		
		HashMap<String, Object> keiInfMap = new HashMap<String, Object>();
		
		// 照査済みフラグ
		// 照査年月日に値が設定されている場合は、"1"(照査済）を設定する。
		// 照査年月日に値が設定されていない場合は、"0"を設定する。
		String shosa_ymd = ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.SHOSA_YMD);
		keiInfMap.put("shous_zumi_flg", (shosa_ymd != null && !"".equals(shosa_ymd)) ? "1" : "0");
		
		// ***** ECK0011A010(お客様一意照会) の実行 *****
		Object[][] eck0011a010IN = {
				// EKK0081A010.SYSID => ＫＥＹ＿SYSID
				{ECK0011A010CBSMsg.KEY_SYSID, ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.SYSID)},
				// "" => ＫＥＹ＿世代登録年月日時分秒
				{ECK0011A010CBSMsg.KEY_GENE_ADD_DTM, ""},
				// 運用日 => ＫＥＹ＿予約適用年月日
				{ECK0011A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null)}
		};
		
		// ◇ SC呼出実行
		CAANMsg eck0011a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_ECK0011A010, "2", eck0011a010IN);
		
		// 処理結果
		CAANMsg[] eck0011a010MsgList = eck0011a010Msg.getCAANMsgList(ECK0011A010CBSMsg.ECK0011A010CBSMSG1LIST);
		
		// お客様一意照会の検索結果が無い場合
		if (eck0011a010MsgList == null || eck0011a010MsgList.length == 0)
		{
			work02Map.put("return_result_cd", "000000");
			return param;
		}

		// 契約者名
		keiInfMap.put("kiyksha_mi", eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.CUST_NM));
		// 契約者名カナ
		keiInfMap.put("kiyksha_mi_kn", eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.CUST_KANA));
		
		// ***** ECK0201B030(連絡先一覧照会(PMP連携用)) の実行 *****
		Object[][] eck0201b030IN = {
				// ECK0011A010.SYSID => ＫＥＹ＿SYSID
				{ECK0201B030CBSMsg.KEY_SYSID, eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.SYSID)},
				// "" => ＫＥＹ＿連絡先番号
				{ECK0201B030CBSMsg.KEY_RRKS_NO, ""}
		};
		
		// ◇ SC呼出実行
		CAANMsg eck0201b030Msg = callSC(handle, param, scCall, TEMPLATE_ID_ECK0201B030, "1", eck0201b030IN);
		
		// 処理結果
		CAANMsg[] eck0201b030MsgList = eck0201b030Msg.getCAANMsgList(ECK0201B030CBSMsg.ECK0201B030CBSMSG1LIST);
		
		for (int i = 0; i < eck0201b030MsgList.length; i++)
		{
			String rrks_bunrui_cd = eck0201b030MsgList[i].getString(ECK0201B030CBSMsg1List.RRKS_BUNRUI_CD);
			String rrks_sbt_cd = eck0201b030MsgList[i].getString(ECK0201B030CBSMsg1List.RRKS_SBT_CD);
			String rrk_way_cd = eck0201b030MsgList[i].getString(ECK0201B030CBSMsg1List.RRK_WAY_CD);
			
			// 連絡先分類コード＝"0"(回線系連絡先) かつ 連絡種別コード＝"5"(その他) かつ 連絡方法コード＝"003"(電話番号) の場合
			if ("0".equals(rrks_bunrui_cd) && "5".equals(rrks_sbt_cd) && "003".equals(rrk_way_cd))
			{
				// 勤務先電話番号に電話番号を設定
				keiInfMap.put("knmsk_dnw_bngu", eck0201b030MsgList[i].getString(ECK0201B030CBSMsg1List.TELNO));
			}
			// 連絡先分類コード＝"0"(回線系連絡先) かつ 連絡種別コード＝"2"(携帯) かつ 連絡方法コード＝"003"(電話番号) の場合
			else if ("0".equals(rrks_bunrui_cd) && "2".equals(rrks_sbt_cd) && "003".equals(rrk_way_cd))
			{
				// 携帯・ＰＨＳ番号に電話番号を設定
				keiInfMap.put("kiti_phs_bngu", eck0201b030MsgList[i].getString(ECK0201B030CBSMsg1List.TELNO));
			}
		}
		
		boolean eodnw_nm_hyouz_flg = false;
		
		// ***** EKK0241B003(回線対象サービス契約一覧照会（サービス契約番号）) の実行 *****
		Object[][] ekk0241b003IN = {
				// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
				{EKK0241B003CBSMsg.KEY_SVC_KEI_NO, (String)ccMsg.get("key_svc_kei_no")}
		};
		
		// ◇ SC呼出実行
		CAANMsg ekk0241b003Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0241B003, "1", ekk0241b003IN);
		
		// 処理結果
		CAANMsg[] ekk0241b003MsgList = ekk0241b003Msg.getCAANMsgList(EKK0241B003CBSMsg.EKK0241B003CBSMSG1LIST);
		
		// 回線対象サービス契約テーブルにサービス契約番号で紐づくデータが存在する場合
		if (ekk0241b003MsgList != null && 0 < ekk0241b003MsgList.length)
		{
			String svc_kei_kaisen_ucwk_no = ekk0241b003MsgList[0].getString(EKK0241B003CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO);
			
			// ***** EKK0251A010(サービス契約回線内訳一意照会) の実行 *****
			Object[][] eck0251a010IN = {
					// EKK0241B003.サービス契約回線内訳番号 => ＫＥＹ＿サービス契約回線内訳番号
					{EKK0251A010CBSMsg.KEY_SVC_KEI_KAISEN_UCWK_NO, svc_kei_kaisen_ucwk_no},
					// "" => ＫＥＹ＿世代登録年月日時分秒
					{EKK0251A010CBSMsg.KEY_GENE_ADD_DTM, ""}
			};
			
			// ◇ SC呼出実行
			CAANMsg eck0251a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0251A010, "2", eck0251a010IN);
			
			// 処理結果
			CAANMsg[] eck0251a010MsgList = eck0251a010Msg.getCAANMsgList(EKK0251A010CBSMsg.EKK0251A010CBSMSG1LIST);
			
			// ※ 回線対象サービス契約.サービス契約回線内訳番号での一意照会であるため、必ずデータが存在する
			
			String state_nm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_STATE_NM);
			String city_nm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_CITY_NM);
			String oaztsu_nm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_OAZTSU_NM);
			String azcho_nm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_AZCHO_NM);
			String bnchigo = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_BNCHIGO);
			String adrttm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_ADRTTM);
			String adrrm = eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_ADRRM);
			
			// 住所出力編集処理部品(JZMAdOutputEdit.getPtn16)のパターン16を使用して、回線場所都道府県名〜回線場所住所補記・部屋番号を編集
			String[] adInf = JZMAdOutputEdit.getPtn16(state_nm, city_nm, oaztsu_nm, azcho_nm, bnchigo, adrttm, adrrm);
			
			// 端末設置場所郵便番号
			keiInfMap.put("tnmt_stbsho_yubn_bngu", eck0251a010MsgList[0].getString(EKK0251A010CBSMsg1List.KAISEN_PLACE_PCD));
			// 端末設置場所先住所１
			keiInfMap.put("tnmt_stbsho_tduhkn_skchousn_mi", adInf[0]);
			// 端末設置場所先住所２
			keiInfMap.put("tnmt_stbsho_jouk_igin_mi", adInf[1]);
			// 端末設置場所先住所３
			keiInfMap.put("tnmt_stbsho_jusho_etc", adInf[2]);
			
			// サービス契約.サービスコードが"02"(電話サービス)の場合
			if ("02".equals(ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.SVC_CD)))
			{
				// ***** EKK0241B002(回線対象サービス契約一覧照会) の実行 *****
				Object[][] ekk0241b002IN = {
						// EKK0241B003.サービス契約回線内訳番号 => ＫＥＹ＿サービス契約回線内訳番号
						{EKK0241B002CBSMsg.KEY_SVC_KEI_KAISEN_UCWK_NO, svc_kei_kaisen_ucwk_no}
				};
				
				// ◇ SC呼出実行
				CAANMsg ekk0241b002Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0241B002, "1", ekk0241b002IN);
				
				// 処理結果
				CAANMsg[] ekk0241b002MsgList = ekk0241b002Msg.getCAANMsgList(EKK0241B002CBSMsg.EKK0241B002CBSMSG1LIST);
				
				// 回線対象サービス契約のサービス契約回線内訳番号に紐づく(電話サービスの)サービス契約が１件だけの場合
				if (ekk0241b002MsgList.length == 1)
				{
					eodnw_nm_hyouz_flg = true;
				}
			}
		}
		
		// ｅｏ電話のみ表示
		// (電話サービスの)サービス契約が１件だけの場合、"1"(単独契約)
		// それ以外の場合、"0"(単独契約なし)
		keiInfMap.put("eodnw_nm_hyouz", eodnw_nm_hyouz_flg ? "1" : "0");
		
		// 申込書番号の取得
		String muskm_bngu = getMskmBngu(handle, param, scCall, (String)ccMsg.get("key_svc_kei_no"));
		
		if(null != muskm_bngu)
		{
			// 申込書番号
			keiInfMap.put("muskm_bngu", muskm_bngu);
		}
		
		// ***** EKK2141B001(旧ICSコード変換一覧照会) の実行 *****
		String prc_grp_cd = ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.PRC_GRP_CD);
		
		Object[][] ekk2141b001IN = {
				// "02"（AxM） => ＫＥＹ＿連携先システム識別コード
				{EKK2141B001CBSMsg.KEY_RNK_SAKI_SYS_SKBT_CD, "02"},
				// "04"（料金プランコード）=> ＫＥＹ＿旧ICSコード変換種別コード
				{EKK2141B001CBSMsg.KEY_OLD_ICS_CD_CHG_SBT_CD, "04"},
				// EKK0081A010.料金グループコード => ＫＥＹ＿料金グループコード
				{EKK2141B001CBSMsg.KEY_PRC_GRP_CD, prc_grp_cd},
				// EKK0081A010.料金コースコード => ＫＥＹ＿料金コースコード
				{EKK2141B001CBSMsg.KEY_PCRS_CD, ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.PCRS_CD)},
				// EKK0081A010.料金プランコード => ＫＥＹ＿料金プランコード
				{EKK2141B001CBSMsg.KEY_PPLAN_CD, ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.PPLAN_CD)},
				// ＫＥＹ＿即割有無
				{EKK2141B001CBSMsg.KEY_SOKU_WARI_UM, getSokuWariUm(handle, param, scCall, prc_grp_cd, (String)ccMsg.get("key_svc_kei_no"))}
		};
		
		// ◇ SC呼出実行
		CAANMsg ekk2141b001Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK2141B001, "1", ekk2141b001IN);
		
		// 処理結果
		CAANMsg[] ekk2141b001MsgList = ekk2141b001Msg.getCAANMsgList(EKK2141B001CBSMsg.EKK2141B001CBSMSG1LIST);
		
		if (ekk2141b001MsgList != null && 0 < ekk2141b001MsgList.length)
		{
			// 契約サービス
			keiInfMap.put("kiyk_sbs",  ekk2141b001MsgList[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD));
			// 料金プラン
			keiInfMap.put("ryoukn_prn",  ekk2141b001MsgList[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_PPLAN_CD));
		}
		
		// ***** EKK2141B001(旧ICSコード変換一覧照会) の実行 *****
		Object[][] ekk2141b001IN_stat = {
				// "02"（AxM） => ＫＥＹ＿連携先システム識別コード
				{EKK2141B001CBSMsg.KEY_RNK_SAKI_SYS_SKBT_CD, "02"},
				// "01"（サービス契約ステータス）=> ＫＥＹ＿旧ICSコード変換種別コード
				{EKK2141B001CBSMsg.KEY_OLD_ICS_CD_CHG_SBT_CD, "01"},
				// EKK0081A010.サービス契約ステータス => ＫＥＹ＿サービス契約ステータス
				{EKK2141B001CBSMsg.KEY_SVC_KEI_STAT, ekk0081a010MsgList[0].getString(EKK0081A010CBSMsg1List.SVC_KEI_STAT)}
		};
		
		// ◇ SC呼出実行
		CAANMsg ekk2141b001Msg_stat = callSC(handle, param, scCall, TEMPLATE_ID_EKK2141B001, "1", ekk2141b001IN_stat);
		
		// 処理結果
		CAANMsg[] ekk2141b001Msg_statList = ekk2141b001Msg_stat.getCAANMsgList(EKK2141B001CBSMsg.EKK2141B001CBSMSG1LIST);
		
		if (ekk2141b001Msg_statList != null && 0 < ekk2141b001Msg_statList.length)
		{
			// 契約状態
			keiInfMap.put("kiyk_joti",  ekk2141b001Msg_statList[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_STAT_CD));
		}
		
		// 契約情報リスト
		ArrayList<HashMap<String, Object>> keiInfList = new ArrayList<HashMap<String, Object>>();
		keiInfList.add(keiInfMap);
		ccMsg.put("kei_inf_list", keiInfList);
		
		work02Map.put("return_result_cd", "000000");
		
		return param;
	}
	
	/**
	 * 即割有無の条件値を取得する
	 * 
	 * @param handle
	 * @param param
	 * @param scCall
	 * @param prc_grp_cd
	 * @param key_svc_kei_no
	 * @return 即割有無の条件値
	 * @throws Exception
	 */
	private String getSokuWariUm(SessionHandle handle, 
								IRequestParameterReadWrite param, 
								ServiceComponentRequestInvoker scCall,
								String prc_grp_cd,
								String key_svc_kei_no) throws Exception
	{
		
		// 料金グループコードが "02"(eo光ネットホームタイプ) または "03"(eo光ネットメゾンタイプ)の場合
		if ("02".equals(prc_grp_cd) || "03".equals(prc_grp_cd))
		{
			// ***** EKK0481B001(割引サービス対象契約一覧照会) の実行 *****
			Object[][] ekk0481b001IN = {
					// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
					{EKK0481B001CBSMsg.KEY_SVC_KEI_NO, key_svc_kei_no},
					// "" => ＫＥＹ＿サービス契約内訳番号
					{EKK0481B001CBSMsg.KEY_SVC_KEI_UCWK_NO, ""},
					// "" => ＫＥＹ＿オプションサービス契約番号
					{EKK0481B001CBSMsg.KEY_OP_SVC_KEI_NO, ""},
					// "" => ＫＥＹ＿サブオプションサービス契約番号
					{EKK0481B001CBSMsg.KEY_SBOP_SVC_KEI_NO, ""},
					// "" => ＫＥＹ＿機器提供サービス契約番号
					{EKK0481B001CBSMsg.KEY_KKTK_SVC_KEI_NO, ""},
					// "" => ＫＥＹ＿割引サービス契約番号
					{EKK0481B001CBSMsg.KEY_WRIB_SVC_KEI_NO, ""}
			};
			
			// ◇ SC呼出実行
			CAANMsg ekk0481b001Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0481B001, "1", ekk0481b001IN);
			
			// 処理結果
			CAANMsg[] ekk0481b001MsgList = ekk0481b001Msg.getCAANMsgList(EKK0481B001CBSMsg.EKK0481B001CBSMSG1LIST);
			
			for (int i = 0; i < ekk0481b001MsgList.length; i++)
			{
				// ***** EKK0451A010(割引サービス契約一意照会) の実行 *****
				Object[][] ekk0451a010IN = {
						// EKK0481B001.割引サービス契約番号 => ＫＥＹ＿割引サービス契約番号
						{EKK0451A010CBSMsg.KEY_WRIB_SVC_KEI_NO, ekk0481b001MsgList[i].getString(EKK0481B001CBSMsg1List.WRIB_SVC_KEI_NO)},
						// "" => ＫＥＹ＿世代登録年月日時分秒
						{EKK0451A010CBSMsg.KEY_GENE_ADD_DTM, ""},
						// 運用日 => ＫＥＹ＿予約適用年月日
						{EKK0451A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null)}
				};
				
				// ◇ SC呼出実行
				CAANMsg ekk0451a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0451A010, "2", ekk0451a010IN);
				
				// 処理結果
				CAANMsg[] ekk0451a010MsgList = ekk0451a010Msg.getCAANMsgList(EKK0451A010CBSMsg.EKK0451A010CBSMSG1LIST);
				
				if (ekk0451a010MsgList != null && 0 < ekk0451a010MsgList.length)
				{
					// ***** EKK0841A010(割引サービス一意照会) の実行 *****
					Object[][] ekk0841a010IN = {
							// EKK0451A010.割引サービスコード => ＫＥＹ＿割引サービスコード
							{EKK0841A010CBSMsg.KEY_WRIB_SVC_CD, ekk0451a010MsgList[0].getString(EKK0451A010CBSMsg1List.WRIB_SVC_CD)},
							// "" => ＫＥＹ＿世代登録年月日時分秒
							{EKK0841A010CBSMsg.KEY_GENE_ADD_DTM, ""},
							// 運用日 => ＫＥＹ＿予約適用年月日
							{EKK0841A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null)}
					};
					
					// ◇ SC呼出実行
					CAANMsg ekk0841a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0841A010, "2", ekk0841a010IN);
					
					// 処理結果
					CAANMsg[] ekk0841a010MsgList = ekk0841a010Msg.getCAANMsgList(EKK0841A010CBSMsg.EKK0841A010CBSMSG1LIST);
					
					if (ekk0841a010MsgList != null && 0 < ekk0841a010MsgList.length)
					{
						// 割引タイプコードが"31"（即割）の場合、"1"（有）を返却する
						String wrib_type_cd = ekk0841a010MsgList[0].getString(EKK0841A010CBSMsg1List.WRIB_TYPE_CD);
						if ("31".equals(wrib_type_cd))
						{
							// "1"（有）を返却する
							return "1";
						}
					}
				}
			}
		}
		
		// "0"（無）を返却する
		return "0";
	}
	
	/**
	 * 申込書番号を取得する。
	 * 
	 * @param handle
	 * @param param
	 * @param scCall
	 * @param key_svc_kei_no
	 * @return 申込書番号
	 * @throws Exception
	 */
	private String getMskmBngu(SessionHandle handle,
						IRequestParameterReadWrite param,
						ServiceComponentRequestInvoker scCall,
						String key_svc_kei_no) throws Exception
	{
		// 申込書番号
		String muskm_bngu = null;
		
		// ***** EKU0081B010(サービス契約_工事案件一覧照会) の実行 *****
		Object[][] eku0081b010IN = {
				// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
				{EKU0081B010CBSMsg.KEY_SVC_KEI_NO, key_svc_kei_no}
		};
		
		// ◇ SC呼出実行
		CAANMsg eku0081b010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKU0081B010, "1", eku0081b010IN);
		
		// 処理結果
		CAANMsg[] eku0081b010MsgList = eku0081b010Msg.getCAANMsgList(EKU0081B010CBSMsg.EKU0081B010CBSMSG1LIST);
		
		for (int i = 0; i < eku0081b010MsgList.length; i++)
		{
			// ***** EKU0011A010(工事案件一意照会) の実行 *****
			Object[][] eku0011a010IN = {
					// EKU0081B010.ＫＥＹ＿工事案件番号 => ＫＥＹ＿工事案件番号
					{EKU0011A010CBSMsg.KEY_KOJIAK_NO, eku0081b010MsgList[i].getString(EKU0081B010CBSMsg1List.KOJIAK_NO)}
			};
			
			// ◇ SC呼出実行
			CAANMsg eku0011a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKU0011A010, "1", eku0011a010IN);
			
			// 処理結果
			CAANMsg[] eku0011a010MsgList = eku0011a010Msg.getCAANMsgList(EKU0011A010CBSMsg.EKU0011A010CBSMSG1LIST);
			
			if(null != eku0011a010MsgList && 0 < eku0011a010MsgList.length)
			{
				// 工事案件種別コードが"001"(新設)の場合
				if("001".equals(eku0011a010MsgList[0].getString(EKU0011A010CBSMsg1List.KOJIAK_SBT_CD)))
				{
					// ***** EKU0091B020(申込明細_工事案件一覧照会(工事案件番号)) の実行 *****
					Object[][] eku0091b020IN = {
							// EKU0011A010.ＫＥＹ＿工事案件番号 => ＫＥＹ＿工事案件番号
							{EKU0091B020CBSMsg.KEY_KOJIAK_NO,  eku0081b010MsgList[i].getString(EKU0081B010CBSMsg1List.KOJIAK_NO)}
					};
					
					// ◇ SC呼出実行
					CAANMsg eku0091b020Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKU0091B020, "1", eku0091b020IN);
					
					// 処理結果
					CAANMsg[] eku0091b020MsgList = eku0091b020Msg.getCAANMsgList(EKU0091B020CBSMsg.EKU0091B020CBSMSG1LIST);
					
					if(null != eku0091b020MsgList && 0 < eku0091b020MsgList.length)
					{
						// 申込書番号取得
						muskm_bngu = eku0091b020MsgList[0].getString(EKU0091B020CBSMsg1List.MSKMSHO_NO);
					}
				}
			}
		}
		
		if(null == muskm_bngu)
		{
			// ***** EKK0081B024(サービス契約履歴一覧照会) の実行 *****
			Object[][] ekk0081b024IN = {
					// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
					{EKK0081B024CBSMsg.KEY_SVC_KEI_NO, key_svc_kei_no}
			};
			// ◇ SC呼出実行
			CAANMsg ekk0081b024Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0081B024, "1", ekk0081b024IN);
			// 処理結果
			CAANMsg[] ekk0081b024MsgList = ekk0081b024Msg.getCAANMsgList(EKK0081B024CBSMsg.EKK0081B024CBSMSG1LIST);
			if(null != ekk0081b024MsgList && 0 < ekk0081b024MsgList.length)
			{
				// 申込明細番号取得（サービス契約の履歴における最古世代のレコードより取得）
				String mskm_dtl_no = ekk0081b024MsgList[ekk0081b024MsgList.length - 1].getString(EKK0081B024CBSMsg1List.MSKM_DTL_NO);
				
				// ***** EKK0021A010(申込明細一意照会取得) の実行 *****
				Object[][] ekk0021a010IN = {
						// EKK0081B024.ＫＥＹ＿申込明細番号 => ＫＥＹ＿申込明細番号
						{EKK0021A010CBSMsg.KEY_MSKM_DTL_NO, mskm_dtl_no},
						{EKK0021A010CBSMsg.KEY_GENE_ADD_DTM, ""}
				};
				// ◇ SC呼出実行
				CAANMsg ekk0021a010Msg = callSC(handle, param, scCall, TEMPLATE_ID_EKK0021A010, "2", ekk0021a010IN);
				// 処理結果
				CAANMsg[] ekk0021a010MsgList = ekk0021a010Msg.getCAANMsgList(EKK0021A010CBSMsg.EKK0021A010CBSMSG1LIST);
				if(null != ekk0021a010MsgList && 0 < ekk0021a010MsgList.length)
				{
					// 申込書番号取得
					muskm_bngu = ekk0021a010MsgList[0].getString(EKK0021A010CBSMsg1List.MSKMSHO_NO);
				}
			}
		}
		
		return muskm_bngu;
	}
	
	/**
	 * チェック処理用のサービスインターフェイスを作成し、返却する。
	 * 
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return HashMap<String, Object> サービスインターフェイスマップ
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle, 
												IRequestParameterReadWrite param, 
												String fixedText) throws RequestParameterException
	{
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(SERVICE_ID);
		
		// *** EKK0081A010(サービス契約一意照会) の実行 ***
		Object[][] ekk0081a010IN = {
			// CC.ＫＥＹ＿サービス契約番号 => ＫＥＹ＿サービス契約番号
			{EKK0081A010CBSMsg.KEY_SVC_KEI_NO, (String)ccMsg.get("key_svc_kei_no")},
			// "" => ＫＥＹ＿世代登録年月日時分秒
			{EKK0081A010CBSMsg.KEY_GENE_ADD_DTM, ""},
			// 運用日 => ＫＥＹ＿予約適用年月日
			{EKK0081A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null)}
		};
		
		// ◇ SC呼出実行
		// 上りマッピングの処理結果を取得するためのマップを生成
		HashMap<String, Object> paramMap = editInMsg(param, TEMPLATE_ID_EKK0081A010, "2", ekk0081a010IN);
		
		return paramMap;
	}
	
	/**
	 * SC呼出
	 * @param handle
	 * @param param
	 * @param scCall
	 * @param svcIfId
	 * @param funcCode
	 * @param svcIfMapData
	 * @return CAANMsg
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg callSC(SessionHandle handle, 
							IRequestParameterReadWrite param, 
							ServiceComponentRequestInvoker scCall,
							String svcIfId,
							String funcCode,
							Object[][] svcIfMapData) throws Exception
	{
		
		// ◇ 上りマッピング処理
		// 上りマッピングの処理結果を取得するためのマップを生成
		HashMap<String, Object> paramMap = editInMsg(param, svcIfId, funcCode, svcIfMapData);
		
		// SC呼出実行
		Map<?, ?> result = scCall.run(paramMap, handle);
		
		// 処理結果の判定
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		
		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();
		
		// エラー情報の転記
		editErrorInfo(param, templates, (Integer)result.get(JCMConstants.RET_CD_INT_KEY));
		
		//エラー情報のマップを取得
		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));
		
		int status = templates[0].getInt(JCMConstants.STATUS_INT_KEY);
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(rtnCode) && 0 == status))
		{
			throw new SCCallException("戻り値不正", rtnCode, status);
		}
		
		return ((CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY))[0];
	}
	
	/**
	 * 上りマッピング処理
	 * @param param
	 * @param svcIfId
	 * @param funcCode
	 * @param mapData
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException
	 */
	private HashMap<String, Object> editInMsg(IRequestParameterReadWrite param, 
												String svcIfId, 
												String funcCode,
												Object[][] mapData) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文ID
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		paramMap.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		paramMap.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());
		
		// 【取得元：ユーザエリア(コントロールマップ)】
		// 依頼先ホスト名
		paramMap.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		
		CAANMsg template = new CAANMsg("eo.ejb.cbs.cbsmsg." + svcIfId + "CBSMsg");
		
		// テンプレートID
		template.set(JCMConstants.TEMPLATE_ID_KEY, svcIfId);
		
		// 機能コード
		template.set(JCMConstants.FUNC_CODE_KEY, funcCode);
		
		// オペレータ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);
		
		for (int i = 0; i < mapData.length; i++)
		{
			Object[] mapVal = mapData[i];
			if ("".equals(mapVal[1]))
			{
				template.setNull((String)mapVal[0]);
			}
			else
			{
				template.set((String)mapVal[0], (String)mapVal[1]);
			}
		}
		
		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);
		
		return paramMap;
	}
	
	/**
	 * サービスインターフェイスのエラー情報をマッピングする。
	 * <br>
	 * @param param リクエストパラメータ
	 * @param templates サービスインターフェイスリスト
	 * @param returnCode リターンコード	
	 * @return IRequestParameterReadWrite リクエストパラメータ
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param, 
													CAANMsg[] templates,
													int returnCode) throws RequestParameterException
	{
		for (int i = 0; i < templates.length; i++)
		{
			CAANMsg template = templates[i];
			int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
			if (returnCode != 0)
			{
				templateStatus = 9000;
			}
			if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", templateStatus)) == null)
			{
				templateStatus = 0;
			}
			
			int bpStatus = 0;
			Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
			if (obj == null)
			{
				bpStatus = -1;
			}
			else
			{
				bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
			}
			
			if (templateStatus > bpStatus)
			{
				// BPにサービスコンポーネントのステータスを設定する。
				String formatStatus = String.format("%1$04d", templateStatus);
				String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
				param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
			}
			
			HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(SERVICE_ID);
			
			HashMap<?, ?> mp = template.getHashMap();
			
			Iterator it = mp.keySet().iterator();
			while (it.hasNext())
			{
				String key = (String)it.next();
				if (key.endsWith("_err"))
				{
					int keyIdx = key.lastIndexOf("_err");
					if (inMap.containsKey(key.substring(0, keyIdx)))
					{
						inMap.put(key, mp.get(key));
					}
				}
			}
		}
		
		return param;
	}
}
