/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKEoidLoginJudgeCC
*	ソースファイル名：JKKEoidLoginJudgeCC.java
*   作成者          ：富士通
*   日付            ：2023年01月06日
*＜機能概要＞
*	eoIDログイン後表示判定情報照会の共通コンポーネントクラスです。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   v64.00.00   2023/01/06  FJ)張本     【ANK-4316-00-00】ｅｏアプリ対応
*   v64.00.01   2023/03/02  FJ)張本     【ANK-4316-03-00】【eoアプリ対応】ログイン可否判定条件の変更
*   v66.00.00   2024/05/09  FJ)張本     【ANK-4316-05-00】【eoアプリ対応】退会後（請求書参照期間中）のログイン可否判定条件の変更
*   v71.00.00   2024/02/12  GDC)CE.Poblete 【ANK-4468-00-00 _eo光ネット「シンプルプラン」追加対応】
*   v71.00.01   2024/06/14  FJ)渋谷     【ANK-4468-00-01 _eo光ネット「シンプルプラン」追加対応】
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.check.HalfCharCheck;
import com.fujitsu.futurity.model.common.check.LengthCheck;

import eo.common.constant.JCKStrConst;
import eo.common.constant.JFUStrConst;
import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JKKStringUtil;
import eo.common.util.JPCFomatString;
import eo.ejb.cbs.cbsmsg.ECK0011A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0081B557CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0251B007CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0251B007CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2961B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2961B001CBSMsg1List;


/**
 * eoIDログイン後表示判定情報照会の共通コンポーネントクラスです。
 * <br>
 * @author FJ
 */
public class JKKEoidLoginJudgeCC extends JCKEoAplCtrlBaseCC
{
	/** CCパラメータ：SYSID */
	private static final String REQ_SYSID = "sysid";
	/** CCパラメータ：変換後SYSID */
	private static final String REQ_CHG_SYSID = "_sysid";
	/** CCパラメータ：eoID */
	private static final String RES_EOID = "eoID";
	/** CCパラメータ： 開通後フラグ */
	private static final String RES_AFTER_OPENING_FLG = "afterOpeningFlg";
	/** CCパラメータ： ログイン可フラグ */
	private static final String RES_LOGIN_POSSIBLE_FLG = "loginPossibleFlg";

	/** CCパラメータ： 回線リスト */
	private static final String RES_ACCESS_LIST = "accessList";
	/** CCパラメータ： 回線内訳番号 */
	private static final String RES_ACCESSITEM_NUMBER = "accessItemNumber";
	/** CCパラメータ： 整理番号 */
	private static final String RES_ORGANIZE_NUMBER = "organizeNumber";
	/** CCパラメータ： 照査済フラグ */
	private static final String RES_VERIFICATION_FLG = "verificationFlg";
	/** CCパラメータ： 未開始同時申込コンテンツ有フラグ */
	private static final String RES_NOT_STARTED_CONTENT_FLG = "notStartedContentFlg";
	/** CCパラメータ： 契約タイプ */
	private static final String RES_CONTRACT_TYPE = "contractType";
	/** CCパラメータ： 利用場所郵便番号 */
	private static final String RES_ACCESSZIP_CODE = "accessZipcode";
	/** CCパラメータ： 利用場所住所1 */
	private static final String RES_ACCESS_ADDRESS1 = "accessAddress1";
	/** CCパラメータ： 利用場所住所2 */
	private static final String RES_ACCESS_ADDRESS2 = "accessAddress2";
	/** CCパラメータ： 利用場所住所3 */
	private static final String RES_ACCESS_ADDRESS3 = "accessAddress3";
	/** CCパラメータ： 利用場所住所4 */
	private static final String RES_ACCESS_ADDRESS4 = "accessAddress4";
	/** CCパラメータ： 利用場所住所5 */
	private static final String RES_ACCESS_ADDRESS5 = "accessAddress5";
	/** CCパラメータ： 利用場所住所6 */
	private static final String RES_ACCESS_ADDRESS6 = "accessAddress6";
	/** CCパラメータ： 利用場所住所7 */
	private static final String RES_ACCESS_ADDRESS7 = "accessAddress7";

	/** CCパラメータ： サービス一覧 */
	private static final String RES_SERVICE_LIST = "serviceList";
	/** CCパラメータ： 料金グループコード */
	private static final String RES_FEE_GROUP_CODE = "feeGroupCode";
	/** CCパラメータ： 料金グループ名称 */
	private static final String RES_FEE_GROUP_NAME = "feeGroupName";
	/** CCパラメータ： 契約状態コード */
	private static final String RES_CONTRACT_STATUS_CODE = "contractStatusCode";
	/** CCパラメータ： 契約状態名称 */
	private static final String RES_CONTRACT_STATUS_NAME = "contractStatusName";
	// ANK-4468-00-00  ADD START
	/** CCパラメータ：　料金コースコード */
	private static final String RES_FEE_COURSE_CODE ="pcrsCode";
	/** CCパラメータ： 　料金コース名称 */
	private static final String RES_PRICE_COURSE_NAME = "pcrsName";
	// ANK-4468-00-00  ADD END
	// ANK-4468-00-01 ADD START
	/** CCパラメータ： 　サービス契約番号 */
	private static final String RES_SVC_KEI_NO = "svcKeiNo";
	// ANK-4468-00-01 ADD END


	/** CCパラメータ：ボディ情報 */
	public static final String BODY_INFO = "BODY_INFO";
	/** CCパラメータ：エラー情報 */
	public static final String ERROR_INFO = "ERROR_INFO";
	/** CCパラメータ：エラーコード */
	public static final String ERROR_CODE = "errorCode";
	/** CCパラメータ：エラーメッセージ */
	public static final String ERROR_MESSAGE = "errorMessage";

	/** テンプレートID：サービス契約グループ設定一覧照会 */
	private static final String TEMPLATE_ID_EKK2961B001 = "EKK2961B001";
	/** テンプレートID：サービス契約回線内訳一覧照会 */
	private static final String TEMPLATE_ID_EKK0251B007 = "EKK0251B007";

	/** 作業用マップのキー：運用日 */
	private static final String WORK_KEY_OPEDATE = "opeDate";
	/** 作業用マップのキー：お客様一意照会明細 */
	private static final String WORK_KEY_ECK0011A010CBSMSGLIST = "ECK0011A010CBSMsg1List";

	/** 対象サービス契約ステータス：有効 */
	private static final List<String> SVC_KEI_STAT_YUKO_LIST = Arrays.asList("010", "020", "030", "100", "210", "220");
	/** 対象サービス契約ステータス：照査後 */
	private static final List<String> SVC_KEI_STAT_SHSA_LIST = Arrays.asList("020", "030", "100", "210", "220");
	/** 対象サービス契約ステータス：開始前 */
	private static final List<String> SVC_KEI_STAT_KMAE_LIST = Arrays.asList("010", "020", "030");
	/** 対象サービス契約ステータス：照査締結 */
	private static final List<String> SVC_KEI_STAT_SHSA_TKTU = Arrays.asList("020", "030");

	/** 照査解約：照査NG */
	private static final String SHOSA_DSL_FIN_CD_2 = "2";
	/** ログイン可フラグ：不可 */
	private static final String LOGIN_POSSIBLE_0 = "0";
	/** ログイン可フラグ：可 */
	private static final String LOGIN_POSSIBLE_1 = "1";
	/** 照査済フラグ：未照査 */
	private static final String VERIFICATION_FLG_0 = "0";
	/** 照査済フラグ：照査済 */
	private static final String VERIFICATION_FLG_1 = "1";

	/**
	 *マストステップ実施状況の照会・更新を行う。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @return リクエストパラメータ
	 * @throws Throwable 例外が発生した場合
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite execute(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// eoIDログイン後表示判定情報照会CCマップ
		Map<String, Object> ccMsg = (Map<String, Object>)param.getData(fixedText);
		// 作業用マップ
		Map<String, Object> work = new HashMap<String, Object>();

		try
		{
			// 運用日
			work.put(WORK_KEY_OPEDATE, JPCBPCommon.getOpeDate(null));
			// 単項目チェック
			if (!checkUnitParam(ccMsg, work))
			{
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				return param;
			}

			// 関連チェック
			if (!checkParameter(handle, param, fixedText, ccMsg, work))
			{
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				return param;
			}

			// サービス情報検索処理
			if (!searchKaisenSvcInfo(handle, param, fixedText, ccMsg, work))
			{
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
				return param;
			}

			// 正常終了
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_0000);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, null);
		}
		catch(Exception e)
		{
			// システムエラー
			setResponse(ccMsg, JKKStrConst.RETURN_CD_3001, "");
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
		}
		catch (Throwable throwable)
		{
			// システムエラー
			setResponse(ccMsg, JKKStrConst.RETURN_CD_3001, "");
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, JKKStrConst.RETURN_CD_5000);
		}

		return param;
	}

	/**
	 * 単項目チェック
	 * @param ccMsg eoIDログイン後表示判定情報照会CCマップ
	 * @param work 作業用マップ
	 * @return チェックの判定
	 * @throws Exception
	 */
	private boolean checkUnitParam(
			Map<String, Object> ccMsg, Map<String, Object> work)
	throws Exception
	{
		// エラーリスト
		List<Map<String, String>> errList = new ArrayList<Map<String, String>>();
		Map<String, Object> bodyMap = new HashMap<String, Object>();
		String itemName = null;
		String itemValue = null;

		// SYSID
		itemName = getReqSysid(ccMsg);
		itemValue = (String)ccMsg.get(itemName);

		if (!JKKStringUtil.isNullBlank(itemName))
		{
			// 必須チェック
			if (itemValue == null || "".equals(itemValue))
			{
				// 必須チェックエラーなし
			}
			else if (!HalfCharCheck.isEnNumber1Check(itemValue))
			{
				// 属性チェックエラー
				errList.add(getFormErrInfMap(itemName, itemValue));
			}
			else if (!LengthCheck.isLength1Check(itemValue, 10))
			{
				// 桁数チェックエラー
				errList.add(getLenErrInfMap(itemName, itemValue));
			}
		}

		// エラーが存在する場合
		if (errList.size() > 0)
		{
			// SYSID
			setMapString(bodyMap, REQ_SYSID, (String)ccMsg.get(REQ_SYSID));
			// ボディ部の設定
			ccMsg.put(BODY_INFO, bodyMap);

			ccMsg.put(ERROR_INFO, errList);
			return false;
		}
		
		return true;

	}

	/**
	 * 関連チェックを行います。<br>
	 * ※後続処理に必要な情報の取得も行う。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg eoIDログイン後表示判定情報照会CCマップ
	 * @param work 作業用マップ
	 * @return チェックエラーの場合はfalse、チェックOKの場合はtrue
	 * @throws Throwable 例外が発生した場合
	 */
	private boolean checkParameter(SessionHandle handle, IRequestParameterReadWrite param, String fixedText,
			Map<String, Object> ccMsg, Map<String, Object> work)
	throws Throwable
	{
		// SYSID
		String itemName = getReqSysid(ccMsg);
		String itemValue = (String)ccMsg.get(itemName);
		if (JKKStringUtil.isNullBlank(itemValue))
		{
			// 関連チェックエラー
			setResponse(ccMsg, JKKStrConst.RETURN_CD_1005, REQ_SYSID + JKKStrConst.COLON);
			return false;
		}

		// 運用日
		String opeDate = (String)work.get(WORK_KEY_OPEDATE);

		// 関連チェック(SYSID存在チェック)
		// お客様一意照会
		CAANMsg[] eck0011a010MsgList = callECK0011A010SC(handle, param, fixedText, (String)ccMsg.get(getReqSysid(ccMsg)), opeDate);

		// SYSIDが取得できない場合
		if (eck0011a010MsgList == null || eck0011a010MsgList.length == 0)
		{
			// SYSID存在チェックエラー
			setResponse(ccMsg, JKKStrConst.RETURN_CD_2001, "契約が見つかりません");
			return false;
		}

// ANK-4316-03-00 ADD START
		String custStat = eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.CUST_STAT);
		String custNtaikaiCd = eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.CUST_NTAIKAI_CD);
// ANK-4316-05-00 MOD START
//		// 退会済は対象外
//		if (JCKStrConst.CD00038_ADD_ZUMI.equals(custStat) && JCKStrConst.CD00260_TAIKAI.equals(custNtaikaiCd))
		String dslAfSksnsKh = eck0011a010MsgList[0].getString(ECK0011A010CBSMsg1List.DSL_AF_SKSSNS_KH);
		// 退会済かつ解約後請求書参照可以外は対象外
		if (JCKStrConst.CD00038_ADD_ZUMI.equals(custStat) && JCKStrConst.CD00260_TAIKAI.equals(custNtaikaiCd) && !JCKStrConst.CD00003_PSB.equals(dslAfSksnsKh))
// ANK-4316-05-00 MOD END
		{
			// SYSID存在チェックエラー
			setResponse(ccMsg, JKKStrConst.RETURN_CD_2001, "契約が見つかりません");
			return false;
		}
// ANK-4316-03-00 ADD END

		// お客様一意照会明細を作業用マップに設定
		work.put(WORK_KEY_ECK0011A010CBSMSGLIST, eck0011a010MsgList);

		return true;
	}

	/**
	 * リクエストパラメタよりSYSIDを取得します<br>
	 * @param ccMsg eoIDログイン後表示判定情報照会CCマップ
	 * @return
	 */
	private String getReqSysid(Map<String, Object> ccMsg)
	{
		if (!JKKStringUtil.isNullEmpty(ccMsg.get(REQ_CHG_SYSID)))
		{
			return REQ_CHG_SYSID;
		}
		else if (!JKKStringUtil.isNullEmpty(ccMsg.get(REQ_SYSID)))
		{
			return REQ_SYSID;
		}
		return null;
	}

	/**
	 * サービス情報検索処理を行います。<br>
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param ccMsg eoIDログイン後表示判定情報照会CCマップ
	 * @param work 作業用マップ
	 * @return 該当なしの場合はfalse、OKの場合はtrue
	 * @throws Throwable 例外が発生した場合
	 */
	private boolean searchKaisenSvcInfo(SessionHandle handle, IRequestParameterReadWrite param, String fixedText,
			Map<String, Object> ccMsg, Map<String, Object> work)
	throws Throwable
	{

		// エラーリスト
		List<Map<String, String>> errList = new ArrayList<Map<String, String>>();
		Map<String, Object> bodyMap = new HashMap<String, Object>();
		Map<String, String> errMap = new HashMap<String, String>();

		// SYSID
		String sysid = (String)ccMsg.get(getReqSysid(ccMsg));

		if (!createSvcList(handle, param, fixedText, bodyMap, work, sysid))
		{
// ANK-4316-03-00 DEL START
//			// 該当サービス契約が存在しない場合はエラー
//			setResponse(ccMsg, JKKStrConst.RETURN_CD_2001, "契約が見つかりません");
//			return false;
// ANK-4316-03-00 DEL END
		}

		// SYSID
		setMapString(bodyMap, REQ_SYSID, (String)ccMsg.get(REQ_SYSID));

		// エラーコード
		errMap.put(ERROR_CODE, "");
		// エラーメッセージ
		errMap.put(ERROR_MESSAGE, "");
		errList.add(errMap);
		ccMsg.put(ERROR_INFO, errList);

		ccMsg.put(BODY_INFO, bodyMap);

		return true;
	}

	/**
	 * サービスリストの設定 <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param bodyMap BODYマップ
	 * @param workMap 作業用マップ
	 * @param sysid SYSID
	 * @return 該当なしの場合はfalse、OKの場合はtrue
	 * @throws Throwable
	 */
	private boolean createSvcList(
			SessionHandle handle
			,IRequestParameterReadWrite param
			,String fixedText
			,Map<String, Object> bodyMap
			,Map<String, Object> work
			,String sysid)
			throws Throwable
	{

		// 開通前後フラグの取得
		String openZengoFlg = getOpenZengoFlg(handle, param, sysid, work);

		// 作業用マップに設定
		CAANMsg[] workEKK0081B557 = (CAANMsg[])work.get(WORK_KEY_EKK0081B557CBSMSGLIST);
		// お客様一意照会明細
		CAANMsg eck0011a010MsgList = ((CAANMsg[])work.get(WORK_KEY_ECK0011A010CBSMSGLIST))[0];


		// eoIDの取得
		String eoId = eck0011a010MsgList.getString(ECK0011A010CBSMsg1List.EOID);
		// 卸事業者の取得
		String orsJgsCd = eck0011a010MsgList.getString(ECK0011A010CBSMsg1List.ORSJGS_CD);

		// 開通前後フラグ
		setMapString(bodyMap, RES_AFTER_OPENING_FLG, openZengoFlg);
		// eoID
		setMapString(bodyMap, RES_EOID, eoId);
		// ログイン可フラグ
		setMapString(bodyMap, RES_LOGIN_POSSIBLE_FLG, LOGIN_POSSIBLE_0);

		if (workEKK0081B557 == null || workEKK0081B557.length == 0)
		{
			return false;
		}

		// サービス契約一覧ソート
		sortEKK0081B557(work);

		Map<String, Object> accessMap = new HashMap<String, Object>();
		List<Map<String, Object>> accessList = new ArrayList<Map<String, Object>>();
		List<Map<String, Object>> serviceList = new ArrayList<Map<String, Object>>();
		for (CAANMsg caanMsg : workEKK0081B557)
		{
			String svcCd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_CD);
			String prcGrpCd = caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_CD);
			String pcrsCd = caanMsg.getString(EKK0081B557CBSMsg1List.PCRS_CD);
			// 対象サービス判定
			if (SVC_KEI_STAT_YUKO_LIST.contains(caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT)))
			{
				// 照査NGチェック
				if (!SHOSA_DSL_FIN_CD_2.equals(caanMsg.getString(EKK0081B557CBSMsg1List.SHOSA_DSL_FIN_CD)))
				{
					// 対象サービス判定
					if (judgeTgPrcGrp(prcGrpCd, pcrsCd))
					{
						// ログイン可の契約がある場合、設定する
						if (judgeLoginKa(caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT), prcGrpCd, orsJgsCd))
						{
							setMapString(bodyMap, RES_LOGIN_POSSIBLE_FLG, LOGIN_POSSIBLE_1);
						}
						// ネット(HT)／電話／テレビでパートナー会員は除外
						if (Arrays.asList(JKKStrConst.CD00133_02, JKKStrConst.CD00133_10, JKKStrConst.CD00133_11).contains(prcGrpCd)
								&& !JKKStringUtil.isNullBlank(orsJgsCd))
						{
							continue;
						}

						// 整理番号、または回線内訳番号がブレークしたら、回線リストを追加する
						String seiriNo1 = JKKStringUtil.nullToBlank((String)accessMap.get(RES_ORGANIZE_NUMBER));
						String seiriNo2 = JKKStringUtil.nullToBlank(caanMsg.getString(EKK0081B557CBSMsg1List.SEIRI_NO));
						String kaisenUcwkNo1 = JKKStringUtil.nullToBlank((String)accessMap.get(RES_ACCESSITEM_NUMBER));
						String kaisenUcwkNo2 = JKKStringUtil.nullToBlank(caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO));
						if (!seiriNo1.equals(seiriNo2) || !kaisenUcwkNo1.equals(kaisenUcwkNo2) || !judgeTgKaisenSvc(svcCd, prcGrpCd, pcrsCd))
						{
							// 回線Map
							accessMap = new HashMap<String, Object>();
							// サービスリスト
							serviceList = new ArrayList<Map<String, Object>>();

							// 未開始同時申込コンテンツ（開通前のみ）
							if (OPEN_ZENGO_FLG_0.equals(bodyMap.get(RES_AFTER_OPENING_FLG))
									&& !JKKStringUtil.isNullBlank(caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO)))
							{
								// 未開始同時申込コンテンツ判定
								boolean isContMkmInfStcd01 = judgeContMkmInfStcd01(handle, param, fixedText, 
											caanMsg.getString(EKK0081B557CBSMsg1List.MSKM_DTL_NO), 
											sysid);
								if (isContMkmInfStcd01)
								{
									// 未開始同時申込コンテンツ有
									setMapString(accessMap, RES_NOT_STARTED_CONTENT_FLG, JKKStrConst.CD00002_UMU_1);
								}
							}

							// 整理番号
							setMapString(accessMap, RES_ORGANIZE_NUMBER, caanMsg.getString(EKK0081B557CBSMsg1List.SEIRI_NO));
							// 照査済フラグ
							setMapString(accessMap, RES_VERIFICATION_FLG, VERIFICATION_FLG_0);

							// 回線内訳取得（電気）
							String svcKeikaisenUcwkNo = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO);
							if (JKKStrConst.CD00133_17.equals(prcGrpCd))
							{
								// サービス契約グループ設定一覧照会
								CAANMsg[] eKK2961B001CBSMsg1List =
										callEKK2961B001SC(handle, param, fixedText, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_NO));
								if (eKK2961B001CBSMsg1List != null && eKK2961B001CBSMsg1List.length > 0)
								{
									// サービス契約回線番号
									svcKeikaisenUcwkNo = eKK2961B001CBSMsg1List[0].getString(EKK2961B001CBSMsg1List.SVKEI_GRP_SKBT_NO);
								}
							}

							// 利用場所取得
							if (!JKKStringUtil.isNullBlank(svcKeikaisenUcwkNo))
							{
								// サービス契約回線一意照会
								CAANMsg[] eKK0251B007CBSMsg1List = callEKK0251B007SC(handle, param, fixedText, svcKeikaisenUcwkNo);
								if (eKK0251B007CBSMsg1List != null && eKK0251B007CBSMsg1List.length > 0)
								{
									CAANMsg kk0251Msg = eKK0251B007CBSMsg1List[0];
									// 利用場所
									setMapString(accessMap, RES_ACCESSITEM_NUMBER, svcKeikaisenUcwkNo);
									setMapString(accessMap, RES_ACCESSZIP_CODE, JPCFomatString.hyhunPcd(kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_PCD)));
									setMapString(accessMap, RES_ACCESS_ADDRESS1, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_STATE_NM));
									setMapString(accessMap, RES_ACCESS_ADDRESS2, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_CITY_NM));
									setMapString(accessMap, RES_ACCESS_ADDRESS3, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_OAZTSU_NM));
									setMapString(accessMap, RES_ACCESS_ADDRESS4, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_AZCHO_NM));
									setMapString(accessMap, RES_ACCESS_ADDRESS5, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_BNCHIGO));
									setMapString(accessMap, RES_ACCESS_ADDRESS6, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_ADRTTM));
									setMapString(accessMap, RES_ACCESS_ADDRESS7, kk0251Msg.getString(EKK0251B007CBSMsg1List.KAISEN_PLACE_ADRRM));

									// 契約タイプ
									String keiType = getKeiType(kk0251Msg.getString(EKK0251B007CBSMsg1List.MANSION_BUKKEN_CD));
									setMapString(accessMap, RES_CONTRACT_TYPE, keiType);
								}
							}

							// 回線リストを追加
							accessList.add(accessMap);
							bodyMap.put(RES_ACCESS_LIST, accessList);
						}

						// 照査済フラグ
						if (SVC_KEI_STAT_SHSA_LIST.contains(caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT)))
						{
							setMapString(accessMap, RES_VERIFICATION_FLG, VERIFICATION_FLG_1);
						}

						// サービスMap
						Map<String, Object> serviceMap = new HashMap<String, Object>();
						// サービス
						setMapString(serviceMap, RES_FEE_GROUP_CODE, caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_CD));
						setMapString(serviceMap, RES_FEE_GROUP_NAME, caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_NM));
						setMapString(serviceMap, RES_CONTRACT_STATUS_CODE, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT));
						setMapString(serviceMap, RES_CONTRACT_STATUS_NAME, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT_NM));
						// ANK-4468-00-00  ADD START
						setMapString(serviceMap, RES_FEE_COURSE_CODE, caanMsg.getString(EKK0081B557CBSMsg1List.PCRS_CD));
						setMapString(serviceMap, RES_PRICE_COURSE_NAME, caanMsg.getString(EKK0081B557CBSMsg1List.PCRS_NM));
						// ANK-4468-00-00  ADD END
						// ANK-4468-00-01 ADD START
						setMapString(serviceMap, RES_SVC_KEI_NO, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_NO));
						// ANK-4468-00-01 ADD END
						// サービスを追加
						serviceList.add(serviceMap);
						accessMap.put(RES_SERVICE_LIST, serviceList);

					}
				}
			}
		}

		return !accessList.isEmpty();
	}

	/**
	 * レスポンス項目を設定します。
	 * <br>
	 * @param ccMsg eoIDログイン後表示判定情報照会CCマップ
	 * @param returnCode リターンコード
	 * @param returnMessage リターンメッセージ
	 */
	private void setResponse(Map<String, Object> ccMsg, String errCode, String errMessage)
	throws Exception
	{
		// エラーリスト
		List<Map<String, String>> errList = new ArrayList<Map<String, String>>();

		Map<String, Object> bodyMap = new HashMap<String, Object>();
		Map<String, String> errMap = new HashMap<String, String>();

		// SYSID
		setMapString(bodyMap, REQ_SYSID, (String)ccMsg.get(REQ_SYSID));
		// ボディ部の設定
		ccMsg.put(BODY_INFO, bodyMap);

		// エラーコード
		errMap.put(ERROR_CODE, errCode);
		// エラーメッセージ
		errMap.put(ERROR_MESSAGE, errMessage);
		errList.add(errMap);
		ccMsg.put(ERROR_INFO, errList);

	}

	/**
	 * 単項目チェックの属性エラーマップ作成メソッドです。
	 * 
	 * @param itemName 項目名
	 * @param itemValue 項目値
	 * @return returnMap
	 */
	private Map<String, String> getFormErrInfMap(String itemName, String itemValue)
	{
		Map<String, String> returnMap = new HashMap<String, String>();

		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_1002);
		returnMap.put(ERROR_MESSAGE, itemName + JKKStrConst.COLON + itemValue);

		return returnMap;
	}
	
	/**
	 * 単項目チェックの桁数エラーマップ作成メソッドです。
	 * 
	 * @param itemName 項目名
	 * @param itemValue 項目値
	 * @return returnMap
	 */
	private Map<String, String> getLenErrInfMap(String itemName, String itemValue)
	{
		Map<String, String> returnMap = new HashMap<String, String>();
		
		returnMap.put(ERROR_CODE, JKKStrConst.RETURN_CD_1003);
		returnMap.put(ERROR_MESSAGE, itemName + JKKStrConst.COLON + itemValue);

		return returnMap;
	}

	/**
	 * ログイン可判定 <br>
	 * @param svcKeiStat サービス契約ステータス
	 * @return
	 */
	private boolean judgeLoginKa(String svcKeiStat, String prcGrpCd, String orsJgsCd)
	{
		// 料金グループ（回線）
		List<String> prcGrpCdKaisen =
				Arrays.asList(JKKStrConst.CD00133_02, JKKStrConst.CD00133_03, JKKStrConst.CD00133_04, JKKStrConst.CD00133_10, JKKStrConst.CD00133_11, JKKStrConst.CD00133_13);

		if (prcGrpCdKaisen.contains(prcGrpCd) && JKKStringUtil.isNullBlank(orsJgsCd))
		{
			return SVC_KEI_STAT_YUKO_LIST.contains(svcKeiStat);
		}
		else if (JKKStrConst.CD00133_17.equals(prcGrpCd))
		{
			return SVC_KEI_STAT_SHSA_LIST.contains(svcKeiStat);
		}
		return false;
	}

	/**
	 * 開通前後判定フラグ取得 <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param sysid SYSID
	 * @param workMap 作業用マップ
	 * @return open_zengo_flg
	 * @throws Throwable
	 */
	protected String getOpenZengoFlg(SessionHandle handle, IRequestParameterReadWrite param, String sysid, Map<String, Object> workMap)
			throws Throwable
	{

		// 開通前後判定フラグ取得
		// ※電気／mineo／メールアドレス単独の開通後は含まない
		String openZengoFlg = new JCKGetOpenZengoFlgCC().getOpenZengoFlg(handle, param, sysid);

		// 作業用マップに設定
		CAANMsg[] workEKK0081B557 = (CAANMsg[])param.getMappingWorkArea().get(WORK_KEY_EKK0081B557CBSMSGLIST);
		workMap.put(WORK_KEY_EKK0081B557CBSMSGLIST, workEKK0081B557);

		// 開通前以外は処理しない
		if (!OPEN_ZENGO_FLG_0.equals(openZengoFlg))
		{
			return openZengoFlg;
		}

		boolean status = false;
		boolean isKaisen = false;

		// ※電気／mineo／メールアドレス単独の開通後を判定する
		for (CAANMsg caanMsg : workEKK0081B557)
		{
			// ステータスチェック
			String svcKeiStat = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT);

			if (SVC_KEI_STAT_KMAE_LIST.contains(svcKeiStat))
			{
				// 照査NGチェック
				String shozaDslfinCd = caanMsg.getString(EKK0081B557CBSMsg1List.SHOSA_DSL_FIN_CD);
				String svcCd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_CD);
				String prcGrpCd = caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_CD);
				String pcrsCd = caanMsg.getString(EKK0081B557CBSMsg1List.PCRS_CD);
				if (!SHOSA_DSL_FIN_CD_2.equals(shozaDslfinCd))
				{
					// 対象サービス判定
					if (judgeTgSvc(svcCd, prcGrpCd, pcrsCd))
					{
						// 開通後判定
						if (judgeWithoutKaisenSvc(svcCd, prcGrpCd))
						{
							// mineo、電気、メールアドレスで照査、締結の契約が存在する
							if (SVC_KEI_STAT_SHSA_TKTU.contains(svcKeiStat))
							{
								status = true;
							}
						}
						else
						{
							isKaisen = true;
						}
					}
				}
			}

			if (status && !isKaisen)
			{
				// 回線なしで１つでも開通後が存在する場合は開通後を返却
				openZengoFlg = OPEN_ZENGO_FLG_1;
				break;
			}
		}

		return openZengoFlg;
	}

	/**
	 * 対象サービス判定 <br>
	 * @param prcGrpCd 料金グループコード
	 * @param pcrsCd 料金コースコード
	 * @return
	 */
	private boolean judgeTgPrcGrp(String prcGrpCd, String pcrsCd)
	{
		// 料金グループコードで判定 
		// 　02 :ｅｏ光ネットホームタイプ
		// 　03 :ｅｏ光ネットメゾンタイプ
		// 　04 :ｅｏ光ネットマンションタイプ
		// 　10 :ｅｏ光電話
		// 　11 :ｅｏ光テレビ
		// 　13 :ｅｏ光テレビ（再送信）※再送信多ch、再送信地デジ・BSは返却対象、再送信は返却対象外
		// 　16 :ｅｏメールアドレス
		// 　17 :ｅｏ電気
		// 　51 :ｍｉｎｅｏ
		return 
		Arrays.asList(JKKStrConst.CD00133_02, 
				JKKStrConst.CD00133_03, 
				JKKStrConst.CD00133_04, 
				JKKStrConst.CD00133_10, 
				JKKStrConst.CD00133_11,
				JKKStrConst.CD00133_13, 
				JKKStrConst.CD00133_16, 
				JKKStrConst.CD00133_17, 
				JKKStrConst.CD00133_51).contains(prcGrpCd)
				&& !JKKStrConst.CD00134_A23.equals(pcrsCd);
	}

	/**
	 * 契約タイプ取得 <br>
	 * @param mansionBukkenCd サービス契約番号
	 * @return
	 * @throws Throwable 
	 */
	private String getKeiType(String mansionBukkenCd) throws Throwable
	{
		if (JKKStrConst.MANSION_BUKKEN_CD_MANSION.equals(mansionBukkenCd))
		{
			// マンション
			return "03";
		}
		else if (JKKStrConst.MANSION_BUKKEN_CD_MEZON.equals(mansionBukkenCd))
		{
			// メゾン
			return "02";
		}
		else
		{
			// ホーム
			return "01";
		}
	}

	/**
	 * サービス契約グループ設定一覧照会サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param svcKeiNo サービス契約番号
	 * @throws Throwable
	 */
	private CAANMsg[] callEKK2961B001SC(SessionHandle handle, 
			IRequestParameterReadWrite param, 
			String fixedText, 
			String svcKeiNo) throws Throwable
	{
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		Object[][] paramIn =
		{
			{EKK2961B001CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK2961B001}
			// 機能コード
			, {EKK2961B001CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1}
			// ＫＥＹ＿サービス契約番号
			, {EKK2961B001CBSMsg.KEY_SVC_KEI_NO, svcKeiNo}
			// ＫＥＹ＿サービス契約グループ種別コード（固定値"01"同一利用場所)
			, {EKK2961B001CBSMsg.KEY_SVKEI_GRP_SBT_CD, JFUStrConst.CD01674_01}
		};
		// サービスIF実行
		CAANMsg[] EKK2961B001CBSMsg1List = callSC(handle, scCall, param, fixedText, paramIn)
				.getCAANMsgList(EKK2961B001CBSMsg.EKK2961B001CBSMSG1LIST);

		return EKK2961B001CBSMsg1List;
	}

	/**
	 * サービス契約回線内訳一意照会サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @param svcKeikaisenUcwkNo サービス契約回線内訳番号
	 * @throws Throwable
	 */
	private CAANMsg[] callEKK0251B007SC(SessionHandle handle, 
			IRequestParameterReadWrite param, 
			String fixedText, 
			String svcKeikaisenUcwkNo) throws Throwable
	{
		// SC呼び出し部品のインスタンス生成
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		Object[][] paramIn =
		{
			{EKK0251B007CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0251B007}
			// 機能コード
			, {EKK0251B007CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1}
			// ＫＥＹ＿サービス契約回線内訳番号
			, {EKK0251B007CBSMsg.KEY_SVC_KEI_KAISEN_UCWK_NO, svcKeikaisenUcwkNo}
		};
		// サービスIF実行
		CAANMsg[] EKK0251B007CBSMsg1List = callSC(handle, scCall, param, fixedText, paramIn)
				.getCAANMsgList(EKK0251B007CBSMsg.EKK0251B007CBSMSG1LIST);

		return EKK0251B007CBSMsg1List;
	}

	/**
	 * サービス契約一覧照会をソートします。
	 * <br>
	 * @param workMap 作業用マップ
	 */
	private void sortEKK0081B557(Map<String, Object> workMap)
	{
		// 作業用マップに設定
		CAANMsg[] workEKK0081B557 = (CAANMsg[])workMap.get(WORK_KEY_EKK0081B557CBSMSGLIST);

		List<CAANMsg> EKK0081B557List = Arrays.asList(workEKK0081B557);
		if (EKK0081B557List.size() > 0)
		{
			// サービス契約結果リストをサービス契約内訳番号の昇順でソート
			Collections.sort(EKK0081B557List, new Comparator<CAANMsg>()
			{
				/**
				 * サービス契約照会結果リストを比較
				 * サービス契約回線内訳番号(昇順)、申込明細番号(昇順)で並び替えます。
				 * @param map1
				 * @param map2
				 * @return サービス契約内訳番号の比較結果
				 */
				public int compare(CAANMsg map1, CAANMsg map2)
				{
					String ucwkNo1 = JKKBPActCommon.nvl((String)map1.getString(EKK0081B557CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO),"999999999999");
					String ucwkNo2 = JKKBPActCommon.nvl((String)map2.getString(EKK0081B557CBSMsg1List.SVC_KEI_KAISEN_UCWK_NO),"999999999999");
					String seiriNo1 = JKKStringUtil.nullToBlank((String)map1.getString(EKK0081B557CBSMsg1List.SEIRI_NO));
					String seiriNo2 = JKKStringUtil.nullToBlank((String)map2.getString(EKK0081B557CBSMsg1List.SEIRI_NO));
					String mskmDtlNo1 = JKKStringUtil.nullToBlank((String)map1.getString(EKK0081B557CBSMsg1List.MSKM_DTL_NO));
					String mskmDtlNo2 = JKKStringUtil.nullToBlank((String)map2.getString(EKK0081B557CBSMsg1List.MSKM_DTL_NO));

					// サービス契約回線内訳番号で並び替える(昇順)
					int result = ucwkNo1.compareTo(ucwkNo2);
					if (result != 0)
					{
						// 同一でない場合は、並び替える
						return result;
					}
					// 整理番号で並び替える(昇順)
					result = seiriNo1.compareTo(seiriNo2);
					if (result != 0)
					{
						// 同一でない場合は、並び替える
						return result;
					}
					// 申込明細番号で並び替える(昇順)
					result = mskmDtlNo1.compareTo(mskmDtlNo2);
					if (result != 0)
					{
						// 同一でない場合は、並び替える
						return result;
					}

					return 0;
				}
			});
		}
		workMap.put(WORK_KEY_EKK0081B557CBSMSGLIST, (CAANMsg[])EKK0081B557List.toArray());
	}
}
