/********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：JKKAdchgKakuteiKikiDslCC
 *  ソースファイル名：JKKAdchgKakuteiKikiDslCC.java
 *  作成者          ：FJ
 *  日付            ：2014年09月24日
 *＜機能概要＞
 *  機器提供サービス契約解約（住所変更）CC部品
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v10.00.00   2014/09/25  FJ          新規作成
 *  v19.00.00   2015/12/04  FJ)星野     OM-2015-0000690対応
*	v19.01.00	2015/12/04	FJ)星野		OM-2015-0000962対応
 *	v20.00.00	2016/01/13	FJ)谷口		OM-2015-0003334対応
 *  v23.01.00   2016/05/10  FJ)森脇     OM-2016-0001043対応
 *  v61.00.00	2023/01/04	FJ)澤田		【ANK-4315-00-00】【eo定期】 eoホームゲートウェイ導入対応
 *  v72.00.00	2025/01/29  FJ)舘山    【#83584】HGW瑕疵内対応（grep対応洩れ）
 ********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKAdchgConstCC;
import com.fujitsu.futurity.bp.custom.constant.JKKAdchgHakkoSODConstCC;
import com.fujitsu.futurity.bp.custom.constant.JKKHakkoSODConstCC;
import com.fujitsu.futurity.bp.custom.constant.JKKSvcConst;
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.CCException;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.sun.enterprise.tools.common.util.StringUtils;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JKKStringUtil;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0251A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0251B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341B002CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341B029CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0341B031CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341B032CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341B504CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0341C330CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0341C340CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0341C540CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1681B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1681B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK1681C040CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2091A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2101B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2811A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2811B010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2811C140CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2811C150CBSMsg;

public class JKKAdchgKakuteiKikiDslCC  extends AbstractCommonComponent {
	
	/** サービスインタフェース呼び出しで使用するマッパー群 */
	private JKKAdchgMapperCC mapper = null;
	
	/** SC呼び出し部品 */
	ServiceComponentRequestInvoker scCall = null;
	
	/** 機器提供サービスコード C005：モデム */
	private static final String KKTK_SVC_CD_MODEM = "C005";
	
	/** 機器提供サービスコード C006：スプリッター */
	private static final String KKTK_SVC_CD_SPLITER = "C006";
	
	/** 機器提供サービスコード C008：インラインフィルタ */
	private static final String KKTK_SVC_CD_INLINE_FILTER = "C008";
	
	/** 機器提供サービスコード C012：ONU */
	private static final String KKTK_SVC_CD_ONU = "C012";
	
	/** 機器提供サービスコード C013：V-ONU */
	private static final String KKTK_SVC_CD_V_ONU = "C013";
	
	/** 機器提供サービスコード C024：多機能ルータ */
	private static final String KKTK_SVC_CD_TAKINO = "C024";
	
	/** 機器オプションサービスコード G01：ルータオプション */
	private static final String KKOP_RUTER = "G01";
	
	/** 機器オプションサービスコード G02：ＶＡオプション */
	private static final String KKOP_VA = "G02";
	
//	/** サービス契約所持情報マップ */
//	HashMap<String, Boolean> svcExistFlgMap;
//	
//	/** サービス契約解約情報マップ */
//	HashMap<String, Boolean> svcDslFlgMap;
	// ANK-4315-00-00 ADD START
	/** 異動予約一覧照会 */
	public static final String TEMPLATE_ID_EKK1681B001 = "EKK1681B001";
	
	/** 異動予約予約適用年月日変更 */
	private static final String TEMPLATE_ID_EKK1681C040 = "EKK1681C040";

	/** 回線に紐づく機器(HGWは除く) */
	private static List<String> kaisenKikiList = Arrays.asList(new String[]{JKKStrConst.KKTK_SVC_CD_TAKINORT, JKKStrConst.CD00132_ONU});

	// ANK-4315-00-00 ADD END
	/**
	 * コンストラクタ
	 */
	public JKKAdchgKakuteiKikiDslCC(){
	}
	
	/**
	 * 初期化処理
	 * 
	 * <br>
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return void
	 * @throws Throwable 
	 */
	private void init(IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// マッパーの初期化
		if (null == this.mapper)
		{
			this.mapper = new JKKAdchgMapperCC();
		}
		
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない。
		if (null == this.scCall)
		{
			this.scCall = new ServiceComponentRequestInvoker();
		}
		
	}

	/**
	 * 転居先に紐づく機器の解約処理
	 * <br>
	 * @param   handle     セッションマネージャなどを持ったハンドル情報
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Throwable  例外が発生した場合
	 * @return  リクエストパラメータ(param)に戻り値を追加して返却する
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite executeKikiDsl(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable {
		
		// 初期処理
		init(param, fixedText);
		
		// 処理に必要な情報をパラメータより取得
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		if (paramMap == null || paramMap.isEmpty()) {
			return param;
		}
		
		// 住所変更番号の取得（番号がない場合は処理を終了する）
		String adchgNo = (String)paramMap.get( "adchg_no" );
		if(StringUtils.isEmpty(adchgNo)){
			return param;
		}
		
		// 住変明細のリストを取得する（取得できない場合は処理を終了する）
		ArrayList<HashMap<String, Object>> kk2101_b001_list = this.callEKK2101B001(handle, param, fixedText, adchgNo, "01");
		if (kk2101_b001_list == null || kk2101_b001_list.size() == 0){
			return param;
		}
		
		// ネットサービス存在フラグ
		boolean isNetExist = false;
		String svcKeiNoNet = null;
		// 電話サービス存在フラグ
		boolean isTelExist = false;
		String svcKeiNoTel = null;
		// テレビサービス存在フラグ
		boolean isTvExist = false;
		String svcKeiNoTv = null;

		// ANK-4315-00-00 ADD START
		// 解約希望日
		String dslKiboYmdAft = (String)paramMap.get( JKKAdchgConstCC.PARAM_KEY_TPPV_TKKJ_DSL_KIBO_YMD );
		// ANK-4315-00-00 ADD END
		
		// 取得した住変明細のリストから転居先のサービス契約番号を取得し、サービス契約を取得する
		for (HashMap<String, Object> adchgDtlMap : kk2101_b001_list){
			// サービス契約番号の取得
			/* ++++++++++ v19.00.00 MOD START ++++++++++ */
//			String svcKeiNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			String chafSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			String chbfSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
			
			String svcKeiNo;
			// サービス解約・残置の場合、変更前識別契約番号を使用
			if(StringUtils.isEmpty(chafSkbtNo)){
				svcKeiNo = chbfSkbtNo;
				
			// 以外はこれまでどおり変更後識別番号を使用
			}else{
				svcKeiNo = chafSkbtNo;
			}
			/* ++++++++++ v19.00.00 MOD END   ++++++++++ */
			if(StringUtils.isEmpty(svcKeiNo)){
				continue;
			}
			
			// サービス契約の取得
			HashMap<String, Object> svcKeiMap = this.callEKK0081A010(handle, param, fixedText, svcKeiNo);
			
			// サービス契約が取得できない場合は次のループへ
			if (svcKeiMap == null) {
				continue;
			}
			
			// サービス契約のステータスが解約済またはキャンセル済の場合
			// または変更後識別番号が未設定（=サービス解約・残置）の場合
			String svcKeiStat = (String)svcKeiMap.get(EKK0081A010CBSMsg1List.SVC_KEI_STAT);
			if(JKKSvcConst.SVC_KEI_STAT_910.equals(svcKeiStat) || JKKSvcConst.SVC_KEI_STAT_920.equals(svcKeiStat)
			/* ++++++++++ v19.00.00 ADD START ++++++++++ */
				|| StringUtils.isEmpty(chafSkbtNo)
			/* ++++++++++ v19.00.00 ADD END   ++++++++++ */
			) {
				// サービスコードの取得
				String svcCd = (String)svcKeiMap.get(EKK0081A010CBSMsg1List.SVC_CD);
				
				// ネット
				if(JKKStrConst.CD00130_01.equals(svcCd)){
					svcKeiNoNet = svcKeiNo;
					// 存在フラグは立てない
					
				// 電話
				}else if(JKKStrConst.CD00130_02.equals(svcCd)){
					svcKeiNoTel = svcKeiNo;
					// 存在フラグは立てない
					
				// テレビ
				}else if(JKKStrConst.CD00130_03.equals(svcCd)){
					svcKeiNoTv = svcKeiNo;
					// 存在フラグは立てない
				}
				
			// サービス契約のステータスが解約済・キャンセル済以外の場合
			}else{
				// サービスコードの取得
				String svcCd = (String)svcKeiMap.get(EKK0081A010CBSMsg1List.SVC_CD);
				
				// ネット
				if(JKKStrConst.CD00130_01.equals(svcCd)){
					svcKeiNoNet = svcKeiNo;
					isNetExist = true;
					
				// 電話
				}else if(JKKStrConst.CD00130_02.equals(svcCd)){
					svcKeiNoTel = svcKeiNo;
					isTelExist = true;
					
				// テレビ
				}else if(JKKStrConst.CD00130_03.equals(svcCd)){
					svcKeiNoTv = svcKeiNo;
					isTvExist = true;
				}

			}
		}
		
		// 住所変更の取得処理
		HashMap<String, Object> adchgMap = this.callEKK2091A010(handle, param, fixedText, adchgNo);
		
		// 住所変更のデータが取得できない場合は処理終了
		if (adchgMap == null) {
			return param;
		}
		
		// 回線に紐づく機器の解約処理
		ArrayList<HashMap<String, Object>> dslKktkList = new ArrayList<HashMap<String, Object>>();
		ArrayList<HashMap<String, Object>> dslKkopList = new ArrayList<HashMap<String, Object>>();
		String svcKeiKaisenUcwkNo = (String)adchgMap.get(EKK2091A010CBSMsg1List.ITENS_SVKEI_KISUW_NO);
		this.dslKaisenKiki(handle, param, fixedText, svcKeiKaisenUcwkNo, isNetExist, isTelExist, isTvExist, svcKeiNoNet, svcKeiNoTel, svcKeiNoTv, dslKktkList, dslKkopList);

		// 配送取消処理
		haisoCancel(handle, param, dslKktkList);
		
		
		
		/* ++++++++++ v19.01.00 ADD START ++++++++++ */
		ArrayList<HashMap<String, Object>> kokanCancelKktkList = new ArrayList<HashMap<String, Object>>();
		// 交換予定だった機器の交換取消処理 リスト作成
		createKokanCancelKikiList(handle, param, fixedText, adchgNo, isNetExist, isTelExist, isTvExist, svcKeiNoNet, svcKeiNoTel, svcKeiNoTv, kokanCancelKktkList);
		
		// 配送取消処理（交換取消前に実施要）
		haisoCancel(handle, param, kokanCancelKktkList);
		
		for(HashMap<String, Object> kk0341_a010_map : kokanCancelKktkList){
			// 交換取消
			executeKokanCancelKiki(handle, param, fixedText, kk0341_a010_map);

		}
		/* ++++++++++ v19.01.00 ADD END   ++++++++++ */
		
		// ＳＯＤ発行処理
		hakkoSODKktkDsl(handle, param, fixedText, dslKktkList, dslKkopList);
		// ANK-4315-00-00 ADD START
		String itnmSvcKeiKaisenUcwkNo = (String)adchgMap.get(EKK2091A010CBSMsg1List.ITNM_SVKEI_KISUW_NO);

		for (HashMap<String, Object> adchgDtlMap : kk2101_b001_list)
		{
			// サービス契約番号の取得
			String chafSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			String chbfSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
			String adchgDtlSbtCd = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.ADCHG_DTL_SBT_CD);
			String chgTgKeiNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHG_TG_KEI_NO);
			//機器提供サービス
			if ("03".equals(adchgDtlSbtCd) && !JKKStringUtil.isNullBlank(chgTgKeiNo))
			{
				// 機器提供サービス契約一意照会
				HashMap<String,Object> kikiMap = getEKK0341A010(handle, param, fixedText, chgTgKeiNo);
				if(kikiMap==null || kikiMap.isEmpty())
				{
					continue;
				}
				
				// 機器が解約済またはキャンセル済みの場合は次のループへ
				String kktkSvcKeiStat = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_STAT);
				if(JKKSvcConst.SVC_KEI_STAT_910.equals(kktkSvcKeiStat) || JKKSvcConst.SVC_KEI_STAT_920.equals(kktkSvcKeiStat)) {
					continue;
				}
				
				// 機器提供サービスコードの取得
				String kktkSvcCd = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_CD);
				
				// 移転先にHGWが存在する場合
				if (JKKStrConst.KKTK_SVC_CD_HGW.equals(kktkSvcCd))
				{
					// 多機能ルーター,ONUを解約する。
					callkikiIdoYoyakuHanei(handle, param, fixedText, itnmSvcKeiKaisenUcwkNo, kaisenKikiList, kk2101_b001_list, dslKiboYmdAft);
				}
			}
		}
		// ANK-4315-00-00 ADD END
		
		return param;
	}
	
	/**
	 * 回線に紐づく機器の解約処理
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param svcKeiKaisenUcwkNo サービス契約回線内訳番号
	 * @throws Throwable
	 */
	private void dslKaisenKiki(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String svcKeiKaisenUcwkNo,
			boolean isNetExist,
			boolean isTelExist,
			boolean isTvExist,
			String svcKeiNoNet,
			String svcKeiNoTel,
			String svcKeiNoTv,
			ArrayList<HashMap<String, Object>> dslKktkList,
			ArrayList<HashMap<String, Object>> dslKkopList
	) throws Throwable
	{
		// ＣＣ入力パラメータ取得
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		String mskmDtlNoNet = (String)paramMap.get("mskmDtlNoNet");
		String mskmDtlNoTel = (String)paramMap.get("mskmDtlNoTel");
		String mskmDtlNoTv = (String)paramMap.get("mskmDtlNoTv");
		
		String mskmDtlNoNetTel = "";
		if(!StringUtils.isEmpty(mskmDtlNoNet)){
			mskmDtlNoNetTel = mskmDtlNoNet;
		}else if(!StringUtils.isEmpty(mskmDtlNoTel)){
			mskmDtlNoNetTel = mskmDtlNoTel;
		}
		
		
		// 回線に紐づく機器の取得処理
		ArrayList<HashMap<String, Object>> kk0341_b504_list = this.callEKK0341B504(handle, param, fixedText, svcKeiKaisenUcwkNo);
		for(HashMap<String, Object> kk0341B504Map : kk0341_b504_list) {
			
			// 機器提供サービス契約一意照会
			String kktkSvcKeiNo = (String)kk0341B504Map.get(EKK0341B504CBSMsg1List.KKTK_SVC_KEI_NO);
			HashMap<String,Object> kikiMap = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
			if(kikiMap==null || kikiMap.isEmpty()){
				continue;
			}
			
			// 機器が解約済またはキャンセル済みの場合は次のループへ
			String kktkSvcKeiStat = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_STAT);
			if(JKKSvcConst.SVC_KEI_STAT_910.equals(kktkSvcKeiStat) || JKKSvcConst.SVC_KEI_STAT_920.equals(kktkSvcKeiStat)) {
				continue;
			}
			
			// 機器提供サービスコードの取得
			String kktkSvcCd = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_CD);
			
			// ネット・電話に紐づく機器の場合
			if( isNetTelKktkSvcCd(kktkSvcCd) ) {
				
				// 機器が多機能ルータの場合
// ▽▽▽ #83584 Modify START
//				if(KKTK_SVC_CD_TAKINO.equals(kktkSvcCd)){
				if(KKTK_SVC_CD_TAKINO.equals(kktkSvcCd) || JKKStrConst.KKTK_SVC_CD_HGW.equals(kktkSvcCd)){
// △△△ #83584 Modify END
					// 機器オプションおよび多機能ルータの解約処理
					this.executeDslTakinoOp(handle, param, fixedText, kikiMap, isNetExist, isTelExist, svcKeiNoNet, svcKeiNoTel, dslKktkList, dslKkopList);
					
				// 多機能ルータ以外の場合
				}else{
				
					// ネット・電話のいずれも無かったら機器解約処理を実行
					if( !isNetExist && !isTelExist ){
						this.executeDslSvcKeiKiki(handle, param, fixedText, kikiMap, mskmDtlNoNetTel);
						
						// 解約後の状態を一意照会で取得し、解約済リストへ格納
						HashMap<String,Object> kikiMapResult = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
						if(kikiMapResult!=null && !kikiMapResult.isEmpty()){
							
							if(!StringUtils.isEmpty(svcKeiNoNet)){
								// 返品登録用のサービス契約番号をセット
								kikiMapResult.put("svcKeiNo", svcKeiNoNet);
							}else if(!StringUtils.isEmpty(svcKeiNoTel)){
								// 返品登録用のサービス契約番号をセット
								kikiMapResult.put("svcKeiNo", svcKeiNoTel);
							}
							
							dslKktkList.add(kikiMapResult);
						}
					}
				}
				
			// テレビに紐づく機器の場合
			}else if(isTvKktkSvcCd(kktkSvcCd)) {
				
				// テレビが無かったら機器解約処理を実行
				if( !isTvExist ){
					this.executeDslSvcKeiKiki(handle, param, fixedText, kikiMap, mskmDtlNoTv);
					
					// 解約後の状態を一意照会で取得し、解約済リストへ格納
					HashMap<String,Object> kikiMapResult = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
					if(kikiMapResult!=null && !kikiMapResult.isEmpty()){
						// 返品登録用のサービス契約番号をセット
						kikiMapResult.put("svcKeiNo", svcKeiNoTv);

						dslKktkList.add(kikiMapResult);
					}
				}
			}
			
		}
	}
	
	/* ++++++++++ v19.01.00 ADD START ++++++++++ */
	/**
	 * 交換予定だった機器の交換取消処理 リスト作成
	 * @throws Throwable
	 */
	private void createKokanCancelKikiList(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String adchgNo,
			boolean isNetExist,
			boolean isTelExist,
			boolean isTvExist,
			String svcKeiNoNet,
			String svcKeiNoTel,
			String svcKeiNoTv,
			ArrayList<HashMap<String, Object>> kokanCancelKktkList
	) throws Throwable
	{
		HashMap<String, String> condMap = new HashMap<String, String>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		
		// 住所変更明細より機器交換を取得
		/** 住所変更明細スキーマデータの取得（機器提供サービス契約番号） */
		// ・EKK2101B001 住所変更明細一覧照会
		ArrayList<HashMap<String, Object>> kk2101_b001_list = getAdchgDtlList(param, fixedText, handle, adchgNo, JKKAdchgConstCC.CD01241_KKTK_SVC_KEI_NO);
		if(kk2101_b001_list == null || kk2101_b001_list.isEmpty()){
			// 該当データなしの場合リターン
			return;
		}

		for(HashMap<String, Object> kk2101_b001_map : kk2101_b001_list){
			
			// 機器提供サービス契約番号
			String kktkSvcKeiNo = (String) kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHG_TG_KEI_NO);
			
			// 交換レコードの場合
			String chbfSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
			String chafSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			if( !StringUtils.isEmpty(chbfSkbtNo) &&
				!StringUtils.isEmpty(chafSkbtNo) &&
				!chbfSkbtNo.equals(chafSkbtNo)
			){
				// 機器提供サービス契約一意照会（予約手続中含む）
				condMap.clear();
				condMap.put(JKKAdchgMapperCC.COND_KEY_KKTK_SVC_KEI_NO, kktkSvcKeiNo);
				condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, JKKAdchgConstCC.DEFAULT_RSV_APLY_YMD);
				reqMap = mapper.setEKK0341B032(param, fixedText, condMap);
				resMap = scCall.run(reqMap, handle);
				List<HashMap<String, Object>> kk0341_b032_map_af = mapper.getEKK0341B032( param, fixedText, resMap );
				mapper.scResultCheck(param);
				
				HashMap<String, Object> kk0341_a010_map = new HashMap<String, Object>();
				if (kk0341_b032_map_af.size() > 0) {
					kk0341_a010_map = kk0341_b032_map_af.get(0);
				}else{
					continue;
				}
				
				// 機器提供サービス契約ステータス
				String kktkSvcKeiStat = (String)kk0341_a010_map.get(EKK0341B032CBSMsg1List.KKTK_SVC_KEI_STAT);
				// 交換中機器の場合
				if("110".equals(kktkSvcKeiStat)){
					
					// 機器提供サービスコードの取得
					String kktkSvcCd = (String)kk0341_a010_map.get(EKK0341A010CBSMsg1List.KKTK_SVC_CD);
					
					// ネット・電話に紐づく機器の場合
					if( isNetTelKktkSvcCd(kktkSvcCd) ) {
						
						// ネット・電話のいずれも無かったら交換取消を実行
						if( !isNetExist && !isTelExist ){
							
							if(!StringUtils.isEmpty(svcKeiNoNet)){
								// 返品登録用のサービス契約番号をセット
								kk0341_a010_map.put("svcKeiNo", svcKeiNoNet);
							}else if(!StringUtils.isEmpty(svcKeiNoTel)){
								// 返品登録用のサービス契約番号をセット
								kk0341_a010_map.put("svcKeiNo", svcKeiNoTel);
							}
							
							kokanCancelKktkList.add(kk0341_a010_map);
						}
						
					// テレビに紐づく機器の場合
					}else if(isTvKktkSvcCd(kktkSvcCd)) {
						
						// テレビが無かったら交換取消を実行
						if( !isTvExist ){
							// 返品登録用のサービス契約番号をセット
							kk0341_a010_map.put("svcKeiNo", svcKeiNoTv);

							kokanCancelKktkList.add(kk0341_a010_map);
						}
					}
				}
			}
		}

	}

	private ArrayList<HashMap<String, Object>> getAdchgDtlList(
			IRequestParameterReadWrite param, 
			String fixedText,
			SessionHandle handle,
			String adchgNo,
			String adchgDtlSbtCd
		) throws Exception{
			/** 事前準備 */
			HashMap<String, String> condMap = new HashMap<String, String>();
			HashMap<String, Object> reqMap;
			Map<?, ?> resMap;

			
			// SCリクエストInvokerを取得
			ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
			
			condMap.clear();
			condMap.put( JKKAdchgMapperCC.COND_KEY_ADCHG_NO, adchgNo );
			condMap.put( JKKAdchgMapperCC.COND_KEY_ADCHG_DTL_SBT_CD, adchgDtlSbtCd );
			reqMap = mapper.setEKK2101B001( param, fixedText, condMap );
			resMap = scCall.run( reqMap, handle );
			ArrayList<HashMap<String, Object>> kk2101_b001_list = mapper.getEKK2101B001( param, fixedText, resMap );
			mapper.scResultCheck( param );
			return kk2101_b001_list;
		}
	
	private void executeKokanCancelKiki(
		SessionHandle handle,
		IRequestParameterReadWrite param, 
		String fixedText,
		HashMap<String, Object> kk0341_a010_map
	) throws Exception,
			CCException {
		String kktkSvcKeiNo = (String)kk0341_a010_map.get(EKK0341B031CBSMsg1List.KKTK_SVC_KEI_NO);
		String geneAddDtm = (String)kk0341_a010_map.get(EKK0341B031CBSMsg1List.GENE_ADD_DTM);
		String last_upd_dtm = (String)kk0341_a010_map.get(EKK0341B032CBSMsg1List.LAST_UPD_DTM);
		
		HashMap<String, String> updMap = new HashMap<String, String>();
		updMap.put(EKK0341C540CBSMsg.KKTK_SVC_KEI_NO, kktkSvcKeiNo);
		updMap.put(EKK0341C540CBSMsg.GENE_ADD_DTM, geneAddDtm);
		updMap.put(EKK0341C540CBSMsg.RSV_CL_YMD, JCCBPCommon.getOpeDate(null));
		updMap.put(EKK0341C540CBSMsg.RSV_APLY_CD, "3");
		updMap.put(EKK0341C540CBSMsg.UPD_DTM_BF, last_upd_dtm);
			
		HashMap<String, Object> reqUpdMap = mapper.setEKK0341C540( param, fixedText, updMap);
		Map<?, ?> resUpdMap = scCall.run( reqUpdMap, handle);
		mapper.getEKK0341C540( param, fixedText, resUpdMap );
		mapper.scResultCheck( param );
	}
	
	/* ++++++++++ v19.01.00 ADD END   ++++++++++ */

	
	/**
	 * EKK0341A010 機器提供サービス契約一意照会
	 * 
	 * @param kktkSvcKeiNo		機器提供サービス契約番号
	 * @return					機器提供サービス契約一意照会結果
	 * @throws Throwable
	 */
	private HashMap<String, Object> getEKK0341A010(
		SessionHandle handle,
		IRequestParameterReadWrite param,
		String fixedText,
		String kktkSvcKeiNo
	) throws Throwable {

		// EKK2811D010_機器提供サービス契約登録
		HashMap<String, String> condMap = new HashMap<String, String>();
		condMap.put(JKKAdchgMapperCC.COND_KEY_KKTK_SVC_KEI_NO, kktkSvcKeiNo);
		condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, JCCBPCommon.getOpeDate(null));
		HashMap<String, Object> reqMap = mapper.setEKK0341A010(param, fixedText, condMap);

		Map<?, ?> resMap = scCall.run(reqMap, handle);
		HashMap<String, Object> mapEKK0341A010 = mapper.getEKK0341A010(param, fixedText, resMap);
		mapper.scResultCheck(param);
		
		return mapEKK0341A010;
	}

	private boolean isNetTelKktkSvcCd(String kktkSvcCd) {
		return KKTK_SVC_CD_MODEM.equals(kktkSvcCd) 
		|| KKTK_SVC_CD_SPLITER.equals(kktkSvcCd)
		|| KKTK_SVC_CD_INLINE_FILTER.equals(kktkSvcCd)
		|| KKTK_SVC_CD_ONU.equals(kktkSvcCd)
// ▽▽▽ #83584 ADD START
		|| JKKStrConst.KKTK_SVC_CD_HGW.equals(kktkSvcCd)
// △△△ #83584 ADD START
		|| KKTK_SVC_CD_TAKINO.equals(kktkSvcCd);
	}
	
	private boolean isTvKktkSvcCd(String kktkSvcCd) {
		return KKTK_SVC_CD_V_ONU.equals(kktkSvcCd);
	}

	/**
	 * 多機能ルータの機器オプションがすべて解約されているかのチェック処理
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @return 解約されている場合はtrue
	 * @throws Throwable
	 */
	private boolean checkKkopDsl(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String kktkSvcKeiNo
	) throws Throwable
	{
		// 判定用フラグ
		boolean dslFlg = true;
		
		// 機器に紐づく機器オプションサービス契約を取得する
		ArrayList<HashMap<String, Object>> kk2811_b010_list = this.callEKK2811B010(handle, param, fixedText, kktkSvcKeiNo);
		
		// 機器オプションがすべて解約またはキャンセルされていることを確認
		for(HashMap<String, Object> kkopMap : kk2811_b010_list){
			
			// 解約済・キャンセル済でない場合
			String kkopStat = (String)kkopMap.get(EKK2811B010CBSMsg1List.KKOP_SVC_KEI_STAT);
			if(!JKKSvcConst.SVC_KEI_STAT_910.equals(kkopStat) && !JKKSvcConst.SVC_KEI_STAT_920.equals(kkopStat)) {
				// 解約・キャンセルされていないオプションがあるため、falseを返す
				dslFlg = false;
				break;
			}
		}
		
		return dslFlg;
	}
	
	/**
	 * 多機能ルータの機器オプションの解約処理
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param kikiMap 機器提供サービスのマップ
	 * @param svcKeiMap サービス契約のマップ
	 * @throws Throwable
	 */
	private void executeDslTakinoOp(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiMap,
			boolean isNetExist,
			boolean isTelExist,
			String svcKeiNoNet,
			String svcKeiNoTel,
			ArrayList<HashMap<String, Object>> dslKktkList,
			ArrayList<HashMap<String, Object>> dslKkopList
	) throws Throwable
	{
		// 多機能ルータに紐づく機器オプションの取得
		String kktkSvcKeiNo = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_NO);
		ArrayList<HashMap<String, Object>> kk2811_b010_list = this.callEKK2811B010(handle, param, fixedText, kktkSvcKeiNo);
		
		// ＣＣ入力パラメータ取得
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		String mskmDtlNoNet = (String)paramMap.get("mskmDtlNoNet");
		String mskmDtlNoTel = (String)paramMap.get("mskmDtlNoTel");
		
		String svcKeiNoForKiki = null;

		
		// 機器オプションを確認し、親サービスが解約またはキャンセルされている場合は解約・キャンセル処理を行う
		for (HashMap<String, Object> kikiOpListMap : kk2811_b010_list){
			
			// 解約済またはキャンセル済の場合は次のループへ
			String kkopStat = (String)kikiOpListMap.get(EKK2811B010CBSMsg1List.KKOP_SVC_KEI_STAT);
			if(JKKSvcConst.SVC_KEI_STAT_910.equals(kkopStat) || JKKSvcConst.SVC_KEI_STAT_920.equals(kkopStat)) {
				continue;
			}
			
			// 一意検索で機器オプションを取得しなおす
			String kkopSvcKeiNo = (String)kikiOpListMap.get(EKK2811B010CBSMsg1List.KKOP_SVC_KEI_NO);
			HashMap<String, Object> kikiOpMap = getEKK2811A010(handle, param, fixedText, kkopSvcKeiNo);
			if(kikiOpMap==null || kikiOpMap.isEmpty()){
				continue;
			}
			
			// 機器オプションサービスコードの取得
			String kkopSvcCd = (String)kikiOpMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_CD);
			
			// ルータオプションの場合
			if (KKOP_RUTER.equals(kkopSvcCd)) {
				// ネットが解約済の場合は解約・キャンセル処理を行う
				if (!isNetExist) {
					/* ++++++++++ v19.00.00 MOD START ++++++++++ */
//					this.executeDslSvcKeiKikiOp(handle, param, fixedText, kikiOpMap, mskmDtlNoNet);
					this.executeDslSvcKeiKikiOp(handle, param, fixedText, kikiOpMap, StringUtils.isEmpty(mskmDtlNoNet) ? (String)kikiMap.get(EKK0341A010CBSMsg1List.MSKM_DTL_NO) : mskmDtlNoNet);
					/* ++++++++++ v19.00.00 MOD END   ++++++++++ */
					
					// 解約後の状態を一意照会で取得し、解約済リストへ格納
					HashMap<String, Object> kikiOpMapResult = getEKK2811A010(handle, param, fixedText, kkopSvcKeiNo);
					if(kikiOpMapResult!=null && !kikiOpMapResult.isEmpty()){
						kikiOpMapResult.put("svcKeiNo", svcKeiNoNet);
						dslKkopList.add(kikiOpMapResult);
					}
					
					// 多機能返品用のサービス契約番号をセット
					if(!StringUtils.isEmpty(svcKeiNoNet)){
						svcKeiNoForKiki = svcKeiNoNet;
					}
				}
			}
			
			// ＶＡオプションの場合
			if (KKOP_VA.equals(kkopSvcCd)) {
				// 電話が解約済の場合は解約・キャンセル処理を行う
				if (!isTelExist) {
					/* ++++++++++ v19.00.00 MOD START ++++++++++ */
//					this.executeDslSvcKeiKikiOp(handle, param, fixedText, kikiOpMap, mskmDtlNoTel);
					this.executeDslSvcKeiKikiOp(handle, param, fixedText, kikiOpMap,  StringUtils.isEmpty(mskmDtlNoTel) ? (String)kikiMap.get(EKK0341A010CBSMsg1List.MSKM_DTL_NO) : mskmDtlNoTel);
					/* ++++++++++ v19.00.00 MOD END   ++++++++++ */
					
					// 解約後の状態を一意照会で取得し、解約済リストへ格納
					HashMap<String, Object> kikiOpMapResult = getEKK2811A010(handle, param, fixedText, kkopSvcKeiNo);
					if(kikiOpMapResult!=null && !kikiOpMapResult.isEmpty()){
						kikiOpMapResult.put("svcKeiNo", svcKeiNoTel);
						dslKkopList.add(kikiOpMapResult);
					}
					
					// 多機能返品用のサービス契約番号をセット（ネット優先なので、既に設定済なら上書きしない）
					if(!StringUtils.isEmpty(svcKeiNoTel) && StringUtils.isEmpty(svcKeiNoForKiki)){
						svcKeiNoForKiki = svcKeiNoTel;
					}
				}
			}
		}
		
		// 多機能ルータに紐づく機器オプションがすべて解約されているかのチェック
		if (this.checkKkopDsl(handle, param, fixedText, kktkSvcKeiNo)) {
			
			String mskmDtlNoNetTel = "";
			if(!StringUtils.isEmpty(mskmDtlNoNet)){
				mskmDtlNoNetTel = mskmDtlNoNet;
			}else if(!StringUtils.isEmpty(mskmDtlNoTel)){
				mskmDtlNoNetTel = mskmDtlNoTel;
			}
			// すべて解約されている場合は多機能ルータを解約する
			this.executeDslSvcKeiKiki(handle, param, fixedText, kikiMap, mskmDtlNoNetTel);
			
			// 解約後の状態を一意照会で取得し、解約済リストへ格納
			HashMap<String,Object> kikiMapResult = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
			if(kikiMapResult!=null && !kikiMapResult.isEmpty()){
				
				// 返品登録用のサービス契約番号をセット
				kikiMapResult.put("svcKeiNo", svcKeiNoForKiki);
				dslKktkList.add(kikiMapResult);
			}
			
			// 機器オプリストに多機能解約フラグを設定
			for(HashMap kkopMap : dslKkopList){
				kkopMap.put("takinoDslFlg", "1");
			}
		}
	}

	private HashMap<String, Object> getEKK2811A010(SessionHandle handle,
			IRequestParameterReadWrite param, String fixedText,
			String kkopSvcKeiNo) throws Throwable {
		HashMap<String, Object> kikiOpMap;
		ArrayList<HashMap<String, Object>> listEKK2811A010 = this.callEKK2811A010(handle, param, fixedText, kkopSvcKeiNo);
		if(listEKK2811A010==null || listEKK2811A010.isEmpty()){
			kikiOpMap = null;
		}
		kikiOpMap = listEKK2811A010.get(0);
		return kikiOpMap;
	}
	
	/**
	 * 配送取消し
	 * 
	 * @param kktkSvcKeiInfo
	 * @param svcKeiNo
	 * @param paramKey
	 * @throws Throwable
	 */
	private void haisoCancel(
		SessionHandle handle,
		IRequestParameterReadWrite param,
		ArrayList<HashMap<String, Object>> dslKktkList
	) throws Throwable {
		
		if(dslKktkList==null || dslKktkList.isEmpty()){
			return;
		}

		// CC呼出用のパラメータ設定
		ArrayList<HashMap<String, String>> haisoCancelKikiList = new ArrayList<HashMap<String, String>>();
		for(HashMap kktkSvcKeiInfo : dslKktkList){
			HashMap<String, String> haisoCancelKiki = new HashMap<String, String>();
			haisoCancelKiki.put("kktkSvcKeiNo", (String)kktkSvcKeiInfo.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_NO));
			haisoCancelKiki.put("kkChgNo", (String)kktkSvcKeiInfo.get(EKK0341A010CBSMsg1List.KIKI_CHG_NO));
			haisoCancelKiki.put("kikiChgNo", (String)kktkSvcKeiInfo.get(EKK0341A010CBSMsg1List.KIKI_CHG_NO));
			haisoCancelKiki.put("svcKeiNo", (String)kktkSvcKeiInfo.get("svcKeiNo"));
			
			haisoCancelKikiList.add(haisoCancelKiki);
		}
		
		HashMap<String, Object> haisoCancelParam = new HashMap<String, Object>();
		haisoCancelParam.put("haiso_cancel_kiki_list", haisoCancelKikiList);

		String fixedText = "JKKAdchgCancelHaisoCC";
		param.setData(fixedText, haisoCancelParam);

		// 配送取消CC
		JKKAdchgCancelHaisoCC haisoCancelCc = new JKKAdchgCancelHaisoCC();
		haisoCancelCc.kikiHaisoCancel(handle, param, fixedText);
	}
	
	
	private void hakkoSODKktkDsl(
		SessionHandle handle,
		IRequestParameterReadWrite param,
		String fixedText,
		ArrayList<HashMap<String, Object>> dslKktkList,
		ArrayList<HashMap<String, Object>> dslKkopList
	) throws Throwable{
		
		// ＣＣ入力パラメータ取得
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);

		
		// 対象データマップ
		HashMap sodTrgtData = new HashMap<String, Object>();
		
		// サービスオーダ発行処理の引数を生成
		// 対象データリスト
		ArrayList<HashMap<String, Object>> trgtDataList = new ArrayList<HashMap<String, Object>>();
		sodTrgtData.put(JKKHakkoSODConstCC.TRGT_DATA_LIST, trgtDataList);
		
		// SODマップ
		HashMap<String, Object> sodMap = new HashMap<String, Object>();
		trgtDataList.add(sodMap);
		// SOD基本情報
		HashMap<String, Object> sodKihonInfo = new HashMap<String, Object>();
		sodKihonInfo.put(JKKHakkoSODConstCC.INFO_SYSID, paramMap.get("sysid"));
		sodKihonInfo.put(JKKHakkoSODConstCC.INFO_IDO_DIV, "00019");
		sodMap.put(JKKHakkoSODConstCC.SOD_KIHON_INFO, sodKihonInfo);
		sodMap.put(JKKHakkoSODConstCC.SVC_KEI_INFO, new HashMap<String, Object>());
		sodMap.put(JKKHakkoSODConstCC.SVC_KEI_UCWK_INFO, new HashMap<String, Object>());
		// オプションサービス契約情報
		sodMap.put(JKKHakkoSODConstCC.OPSVKEI_INFO, new HashMap<String, Object>());
		// 機器提供サービス契約情報
		sodMap.put(JKKHakkoSODConstCC.KKTSVKEI_INFO, new HashMap<String, Object>());
		
		// 機器オプションサービス契約情報
		ArrayList<HashMap<String, Object>> kkop_trgt_data_list = new ArrayList<HashMap<String, Object>>();
		for(HashMap kkopMap : dslKkopList){
			HashMap<String, Object> kkopsvkeiInfo = new HashMap<String, Object>();
			kkopsvkeiInfo.put(JKKAdchgHakkoSODConstCC.INFO_CHBF_KKOPSVKEI_NO, kkopMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
			kkopsvkeiInfo.put(JKKAdchgHakkoSODConstCC.INFO_CHBF_KKOPSVKEI_GENE_ADD_DTM, kkopMap.get(EKK2811A010CBSMsg1List.GENE_ADD_DTM));
			kkopsvkeiInfo.put(JKKAdchgHakkoSODConstCC.INFO_TAKINO_DSL_FLG, kkopMap.get("takinoDslFlg"));
			kkopsvkeiInfo.put("svcKeiNo", kkopMap.get("svcKeiNo"));
			kkop_trgt_data_list.add(kkopsvkeiInfo);
		}
		sodMap.put(JKKAdchgHakkoSODConstCC.KKOP_TRGT_DATA_LIST, kkop_trgt_data_list);
		
		// 機能コード
		sodTrgtData.put(JCMConstants.FUNC_CODE_KEY, JPCModelConstant.FUNC_CD_1);
		param.setData("JKKAdchgCancelHakkoSODCC", sodTrgtData);
		
		JKKAdchgCancelHakkoSODCC adchgCancelSodCC = new JKKAdchgCancelHakkoSODCC();
		adchgCancelSodCC.hakkoSODKktkDsl(handle, param, "JKKAdchgCancelHakkoSODCC");
	}



	
	
	
	
	/**
	 * 機器提供サービス契約の解約・キャンセル処理
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param kikiMap 機器提供サービスのマップ
	 * @param svcKeiMap サービス契約のマップ
	 * @throws Throwable
	 */
	private void executeDslSvcKeiKiki(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiMap,
			String mskmDtlNo
	) throws Throwable
	{
		// OM-2015-0003334 20160113 ADD START
		// 再度機器提供サービス契約一意照会を行い、更新前年月日時分秒を取得しなおす
		String kktkSvcKeiNo = (String)kikiMap.get(EKK0341B504CBSMsg1List.KKTK_SVC_KEI_NO);
		HashMap<String,Object> kikiMap_wk = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
		// 最終更新年月日時分秒を再設定
		kikiMap.put(EKK0341A010CBSMsg1List.LAST_UPD_DTM, (String)kikiMap_wk.get(EKK0341A010CBSMsg1List.LAST_UPD_DTM));
		// OM-2015-0003334 20160113 ADD END
		
		// 機器のステータスが締結済未満の場合
		String kktkSvcStat = (String)kikiMap.get(EKK0341B002CBSMsg1List.KKTK_SVC_KEI_STAT);
		if (JKKSvcConst.SVC_KEI_STAT_030.compareTo(kktkSvcStat) > 0) {
			// 機器提供サービス契約のキャンセル処理
			this.callEKK0341C330(handle, param, fixedText, kikiMap, mskmDtlNo);
		
		// 機器のステータスが締結済以降の場合
		} else {
			// 機器提供サービス契約の解約処理実行
			HashMap<String, Object> kikiDslMap = this.callEKK0341C340(handle, param, fixedText, kikiMap, mskmDtlNo);
			
			// 機器提供サービス契約の解約確定処理実行
			String lastUpdDtm = (String) kikiDslMap.get(EKK0341C340CBSMsg.UPD_DTM);
			kikiMap.put(JKKAdchgMapperCC.UPD_DT_KKTK_SVC_KEI_UPD_DTM_BEF, lastUpdDtm);
			this.callEKK0341C350(handle, param, fixedText, kikiMap);
		}
	}
	
	/**
	 * 機器オプションサービス契約の解約・キャンセル処理
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param kikiOpMap 機器オプションサービスのマップ
	 * @throws Throwable
	 */
	private void executeDslSvcKeiKikiOp(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiOpMap,
			String mskmDtlNo
	) throws Throwable
	{
		
		// 機器オプションのステータスが締結済未満の場合
		String kkopSvcStat = (String)kikiOpMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_STAT);
		if (JKKSvcConst.SVC_KEI_STAT_030.compareTo(kkopSvcStat) > 0) {
			// 機器オプションサービス契約のキャンセル処理
			this.callEKK2811C110(handle, param, fixedText, kikiOpMap, mskmDtlNo);
		
		// 機器オプションのステータスが締結済以降の場合
		} else {
			// 機器オプションサービス契約の解約処理実行
			HashMap<String, Object> kikiOpDslMap = this.callEKK2811C140(handle, param, fixedText, kikiOpMap, mskmDtlNo);
			
			// 機器オプションサービス契約の解約確定処理実行
			this.callEKK2811C150(handle, param, fixedText, kikiOpMap, (String)kikiOpDslMap.get(EKK2811C140CBSMsg.UPD_DTM));
		}
	}
	
	/**
	 * 住所変更明細一覧照会呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	adchgNo	住所変更番号
	 * @param	adchgDtlSbtNo	住所変更明細識別番号
	 * @return
	 * @throws	Throwable
	 */
	private ArrayList<HashMap<String, Object>> callEKK2101B001(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String adchgNo,
			String adchgDtlSbtNo
	) throws Throwable
	{
		// 住所変更明細検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 住所変更番号と住所変更明細識別番号を設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_ADCHG_NO, adchgNo);
		condMap.put(JKKAdchgMapperCC.COND_KEY_ADCHG_DTL_SBT_CD, adchgDtlSbtNo);
		
		// 住所変更明細一覧照会
		HashMap<String, Object> mapEKK2101B001 = this.mapper.setEKK2101B001(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2101B001, handle);
		ArrayList<HashMap<String, Object>> kk2101_b001_list = mapper.getEKK2101B001( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2101_b001_list;
	}
	
	/**
	 * サービス契約一意照会呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	svcKeiNo サービス契約番号
	 * @return
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK0081A010(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String svcKeiNo
	) throws Throwable
	{
		// サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件を設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNo);
		condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, JCCBPCommon.getOpeDate(null));
		
		// サービス契約一覧照会
		HashMap<String, Object> mapEKK0081A010 = this.mapper.setEKK0081A010(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK0081A010, handle);
		HashMap<String, Object> kk0081_A010 = mapper.getEKK0081A010( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk0081_A010;
	}
	
	/**
	 * 機器提供サービス契約一覧照会（サービス契約回線内訳番号）呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	svcKeiKaisenUcwkNo サービス契約回線内訳番号
	 * @return
	 * @throws	Throwable
	 */
	private  ArrayList<HashMap<String, Object>> callEKK0341B504(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String svcKeiKaisenUcwkNo
	) throws Throwable
	{
		// 機器提供サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件の設定
		condMap.put("key_svc_kei_kaisen_ucwk_no", svcKeiKaisenUcwkNo);
		
		// 機器提供サービス契約一覧照会
		HashMap<String, Object> mapEKK0341B504 = this.mapper.setEKK0341B504(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK0341B504, handle);
		ArrayList<HashMap<String, Object>> kk0341_b504_list = mapper.getEKK0341B504( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk0341_b504_list;
	}
	
	/**
	 * 住所変更一意照会呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	adchgNo 住所変更番号
	 * @return
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK2091A010(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String adchgNo
	) throws Throwable
	{
		// サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件を設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_ADCHG_NO, adchgNo);
		
		// サービス契約一覧照会
		HashMap<String, Object> mapEKK2091A010 = this.mapper.setEKK2091A010(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2091A010, handle);
		HashMap<String, Object> kk2091_A010 = mapper.getEKK2091A010( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2091_A010;
	}
	
	/**
	 * 機器オプションサービス契約一意照会呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kkopSvcKeiNo 機器オプションサービス契約番号
	 * @return
	 * @throws	Throwable
	 */
	private ArrayList<HashMap<String, Object>> callEKK2811A010(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String kkopSvcKeiNo
	) throws Throwable
	{
		// サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件を設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_KKOP_SVC_KEI_NO, kkopSvcKeiNo);
		condMap.put(JKKAdchgMapperCC.COND_KEY_RSV_APLY_YMD, JCCBPCommon.getOpeDate(null));
		
		// サービス契約一覧照会
		HashMap<String, Object> mapEKK2811A010 = this.mapper.setEKK2811A010(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2811A010, handle);
		ArrayList<HashMap<String, Object>> kk2811_A010_List = mapper.getEKK2811A010( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2811_A010_List;
	}
	
	/**
	 * 機器オプションサービス契約一覧照会（機器提供サービス契約番号）呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kktkSvcKeiNo 機器提供サービス契約番号
	 * @return
	 * @throws	Throwable
	 */
	private  ArrayList<HashMap<String, Object>> callEKK2811B010(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String kktkSvcKeiNo
	) throws Throwable
	{
		// 機器オプションサービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件の設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_KKTK_SVC_KEI_NO, kktkSvcKeiNo);
		
		// 機器オプションサービス契約一覧照会
		HashMap<String, Object> mapEKK2811B010 = this.mapper.setEKK2811B010(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2811B010, handle);
		ArrayList<HashMap<String, Object>> kk2811_b010_list = mapper.getEKK2811B010( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2811_b010_list;
	}
	
	/**
	 * 機器提供サービス契約キャンセル呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiMap 機器提供サービスのマップ
	 * @return
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK0341C330(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiMap,
			String mskmDtlNo
	) throws Throwable
	{
		// サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件を設定
		condMap.put(EKK0341C330CBSMsg.KKTK_SVC_KEI_NO, (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_NO));
		condMap.put(EKK0341C330CBSMsg.MSKM_DTL_NO, mskmDtlNo);
		condMap.put(EKK0341C330CBSMsg.SVC_CANCEL_RSN_CD, "01");
		condMap.put(EKK0341C330CBSMsg.IDO_DIV, JKKStrConst.CD00576_ADCHG_ADD);
		condMap.put(EKK0341C330CBSMsg.UPD_DTM_BF, (String)kikiMap.get(EKK0341A010CBSMsg1List.LAST_UPD_DTM));
		
		// 機器提供サービス契約キャンセル処理
		HashMap<String, Object> mapEKK0341C330 = this.mapper.setEKK0341C330(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK0341C330, handle);
		HashMap<String, Object> kk0341_C330 = mapper.getEKK0341C330( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk0341_C330;
	}
	
	/**
	 * 機器提供サービス契約解約処理呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiMap 機器提供サービスのマップ
	 * @return svcKeiMap サービス契約のマップ
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK0341C340(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiMap,
			String mskmDtlNo
	) throws Throwable
	{
		
		// 機器提供サービス契約解約処理実行
		kikiMap.put(JKKAdchgConstCC.PARAM_KEY_MSKM_DTL_NO, mskmDtlNo);
		String opeDate = JCCBPCommon.getOpeDate(null);
		kikiMap.put(EKK0341C340CBSMsg.SVC_ENDYMD, opeDate);
		kikiMap.put(EKK0341C340CBSMsg.SVC_CHRG_ENDYMD, addYYYYMMDD((String) opeDate, -1));
		kikiMap.put(EKK0341C340CBSMsg.PNLTY_HASSEI_CD, null);
		kikiMap.put(JKKAdchgMapperCC.UPD_DT_KKTK_SVC_KEI_UPD_DTM_BEF, kikiMap.get(EKK0341A010CBSMsg1List.LAST_UPD_DTM));
		HashMap<String, Object> mapEKK0341C340 = this.mapper.setEKK0341C340(param, fixedText, kikiMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK0341C340, handle);
		HashMap<String, Object> kk0341_C340 = mapper.getEKK0341C340( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk0341_C340;
	}
	
	/**
	 * 機器提供サービス契約解約確定処理呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiMap 機器提供サービスのマップ
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK0341C350(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiMap
	) throws Throwable
	{
		
		// 機器提供サービス契約解約処理実行
		HashMap<String, Object> mapEKK0341C350 = this.mapper.setEKK0341C350(param, fixedText, kikiMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK0341C350, handle);
		HashMap<String, Object> kk0341_C350 = mapper.getEKK0341C350( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk0341_C350;
	}
	
	/**
	 * 機器オプションサービス契約キャンセル呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiOpMap 機器オプションサービスのマップ
	 * @return
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK2811C110(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiOpMap,
			String mskmDtlNo
	) throws Throwable
	{
		// サービス契約検索用の情報を設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 検索条件を設定
		condMap.put(JKKAdchgMapperCC.COND_KEY_KKOP_SVC_KEI_NO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
		if(!StringUtils.isEmpty(mskmDtlNo)){
			condMap.put(JKKAdchgMapperCC.COND_KEY_MSKM_DTL_NO, mskmDtlNo);
		}else{
			condMap.put(JKKAdchgMapperCC.COND_KEY_MSKM_DTL_NO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.MSKM_DTL_NO));
		}
		condMap.put(JKKAdchgMapperCC.COND_KEY_IDO_DIV, JKKStrConst.CD00576_ADCHG_ADD);
		String lastUpdDtm = (String)kikiOpMap.get(EKK2811A010CBSMsg1List.LAST_UPD_DTM);
		if(!StringUtils.isEmpty(lastUpdDtm)){
			condMap.put("upd_dtm_bf", lastUpdDtm);
		}else{
			condMap.put("upd_dtm_bf", (String)kikiOpMap.get(EKK2811A010CBSMsg1List.UPD_DTM));
		}
		// 機器提供サービス契約キャンセル処理
		HashMap<String, Object> mapEKK2811C110 = this.mapper.setEKK2811C110(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2811C110, handle);
		HashMap<String, Object> kk2811_C110 = mapper.getEKK2811C110( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2811_C110;
	}
	
	/**
	 * 機器オプションサービス契約解約処理呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiOpMap 機器オプションサービスのマップ
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK2811C140(
		SessionHandle handle,
		IRequestParameterReadWrite param,
		String fixedText,
		HashMap<String, Object> kikiOpMap,
		String mskmDtlNo
	) throws Throwable
	{
		// 機器オプションサービス契約解約情報設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 機器オプションサービス契約番号
		condMap.put(EKK2811C140CBSMsg.KKOP_SVC_KEI_NO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
		// 異動区分
		condMap.put(EKK2811C140CBSMsg.IDO_DIV, JKKStrConst.CD00576_ADCHG_ADD);
		// 申込明細番号
		condMap.put(EKK2811C140CBSMsg.MSKM_DTL_NO, mskmDtlNo);
		// 予約適用開始希望年月日
		condMap.put(EKK2811C140CBSMsg.RSV_TSTA_KIBO_YMD, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.RSV_TSTA_KIBO_YMD));
		// サービス終了年月日
		String opeDate = JCCBPCommon.getOpeDate(null);
		condMap.put(EKK2811C140CBSMsg.SVC_ENDYMD, opeDate);
		// サービス課金終了年月日
		condMap.put(EKK2811C140CBSMsg.SVC_CHRG_ENDYMD, addYYYYMMDD((String) opeDate, -1));
		// サービス解約理由コード
		condMap.put(EKK2811C140CBSMsg.SVC_DLRE_CD, "01");
		// サービス解約理由メモ
		condMap.put(EKK2811C140CBSMsg.SVC_DLRE_MEMO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.SVC_DLRE_MEMO));
		// 違約金発生コード
		condMap.put(EKK2811C140CBSMsg.PNLTY_HASSEI_CD, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.PNLTY_HASSEI_CD));
		// 更新年月日時分秒(更新前)
		String lastUpdDtm = (String)kikiOpMap.get(EKK2811A010CBSMsg1List.LAST_UPD_DTM);
		if(!StringUtils.isEmpty(lastUpdDtm)){
			condMap.put(EKK2811C140CBSMsg.UPD_DTM_BF, lastUpdDtm);
		}else{
			condMap.put(EKK2811C140CBSMsg.UPD_DTM_BF, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.UPD_DTM));
		}
		
		// 機器オプションサービス契約解約処理実行
		HashMap<String, Object> mapEKK2811C140 = this.mapper.setEKK2811C140(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2811C140, handle);
		HashMap<String, Object> kk2811_C140 = mapper.getEKK2811C140( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2811_C140;
	}
	
	public static String addYYYYMMDD(String trgtYmd, int addDay) throws Throwable
	{
		// 年月日が空の場合
		if (trgtYmd == null || "".equals(trgtYmd))
		{
			return trgtYmd;
		}

		// 年月日が８桁に満たない場合
		if (trgtYmd.length() < 8)
		{
			return trgtYmd;
		}

		// 年月日の抽出
		int year  = Integer.parseInt(trgtYmd.substring(0, 4));
		int month = Integer.parseInt(trgtYmd.substring(4, 6));
		int day   = Integer.parseInt(trgtYmd.substring(6, 8));

		Calendar cal = Calendar.getInstance();
		cal.set(year, month - 1, day);
		// 日付を算出
		cal.add(Calendar.DATE, addDay);

		return String.format("%tY%tm%td", cal, cal, cal);
	}

	
	/**
	 * 機器オプションサービス契約解約確定処理呼出
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiOpMap 機器オプションサービスのマップ
	 * @throws	Throwable
	 */
	private HashMap<String, Object> callEKK2811C150(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> kikiOpMap,
			String lastUpdDtm
	) throws Throwable
	{
		// 機器オプションサービス契約解約情報設定
		HashMap<String, String> condMap = new HashMap<String, String>();
		
		// 機器オプションサービス契約番号
		condMap.put(EKK2811C150CBSMsg.KKOP_SVC_KEI_NO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
		// サービス終了年月日
		String opeDate = JCCBPCommon.getOpeDate(null);
		condMap.put(EKK2811C150CBSMsg.SVC_ENDYMD, opeDate);
		// サービス課金終了年月日
		condMap.put(EKK2811C150CBSMsg.SVC_CHRG_ENDYMD, addYYYYMMDD((String) opeDate, -1));
		// サービス解約理由コード
		condMap.put(EKK2811C150CBSMsg.SVC_DLRE_CD, "01");
		// サービス解約理由メモ
		condMap.put(EKK2811C150CBSMsg.SVC_DLRE_MEMO, (String)kikiOpMap.get(EKK2811A010CBSMsg1List.SVC_DLRE_MEMO));
		// 更新年月日時分秒(更新前)
		condMap.put(EKK2811C150CBSMsg.UPD_DTM_BF, lastUpdDtm);
		// OM-2016-0001043 ADD START
		condMap.put(EKK2811C150CBSMsg.DSL_JI_CHRG, "1");
		// OM-2016-0001043 ADD END

		
		// 機器オプションサービス契約解約確定処理実行
		HashMap<String, Object> mapEKK2811C150 = this.mapper.setEKK2811C150(param, fixedText, condMap);
		Map<?, ?> resMap = this.scCall.run(mapEKK2811C150, handle);
		HashMap<String, Object> kk2811_C150 = mapper.getEKK2811C150( param, fixedText, resMap );
		mapper.scResultCheck( param );

		return kk2811_C150;
	}
	// ANK-4315-00-00 ADD START
	/**
	 * 機器取得処理後に異動予約の予約適用年月日を更新する
	 * 
	 * @param	handle
	 * @param	param
	 * @param	fixedText
	 * @param	kikiOpMap 機器オプションサービスのマップ
	 * @throws	Throwable
	 */
	private void callkikiIdoYoyakuHanei(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			String svcKeiKaisenUcwkNo,
			List<String> paramKktkSvcCd,
			ArrayList<HashMap<String, Object>> kk2101_b001_list,
			String rsvAplyYmd
	) throws Throwable
	{
		// 回線に紐づく機器の取得処理
		ArrayList<HashMap<String, Object>> kk0341_b504_list = this.callEKK0341B504(handle, param, fixedText, svcKeiKaisenUcwkNo);
		for(HashMap<String, Object> kk0341B504Map : kk0341_b504_list) 
		{
			// 機器提供サービス契約一意照会
			String kktkSvcKeiNo = (String)kk0341B504Map.get(EKK0341B504CBSMsg1List.KKTK_SVC_KEI_NO);
			HashMap<String,Object> kikiMap = getEKK0341A010(handle, param, fixedText, kktkSvcKeiNo);
			if(kikiMap==null || kikiMap.isEmpty()){
				continue;
			}
			
			// 機器が解約済またはキャンセル済みの場合は次のループへ
			String kktkSvcKeiStat = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_STAT);
			if(JKKSvcConst.SVC_KEI_STAT_910.equals(kktkSvcKeiStat) || JKKSvcConst.SVC_KEI_STAT_920.equals(kktkSvcKeiStat)) {
				continue;
			}
			
			// 機器提供サービスコードの取得
			String kktkSvcCd = (String)kikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_CD);
			
			// 多機能とONUの場合
			if (null != paramKktkSvcCd && paramKktkSvcCd.contains(kktkSvcCd))
			{
				for (HashMap<String, Object> adchgDtlMap : kk2101_b001_list)
				{
					// サービス契約番号の取得
					String chafSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
					String chbfSkbtNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
					String adchgDtlSbtCd = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.ADCHG_DTL_SBT_CD);
					String chgTgKeiNo = (String)adchgDtlMap.get(EKK2101B001CBSMsg1List.CHG_TG_KEI_NO);
					//機器提供サービス
					if ("03".equals(adchgDtlSbtCd) && !JKKStringUtil.isNullBlank(chgTgKeiNo) && 
						JKKStringUtil.nullToBlank(kktkSvcKeiNo).equals(chbfSkbtNo) &&
						JKKStringUtil.isNullBlank(chafSkbtNo)
					)
					{
						// 上りマッピング処理(異動予約一覧照会）
						Object[][] ekk1681B001InMsg = {{EKK1681B001CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK1681B001},
														{EKK1681B001CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
														{EKK1681B001CBSMsg.KEY_IDO_RSV_DTL_CD, "013"},
														{EKK1681B001CBSMsg.KEY_IDO_RSV_STAT_CD, JKKStrConst.CD01168_IDO_RSV_STAT_CD_00},
														{EKK1681B001CBSMsg.KEY_KKTK_SVC_KEI_NO, chgTgKeiNo}};
						// SC呼出実行
						CAANMsg[] ekk1681B001outMsg = callSC(handle,
															scCall,
															param,
															fixedText,
															ekk1681B001InMsg).getCAANMsgList(EKK1681B001CBSMsg.EKK1681B001CBSMSG1LIST);
						// 異動予約一覧照会を存在する場合、予約適用日を更新する。
						if (null != ekk1681B001outMsg && 0 < ekk1681B001outMsg.length)
						{
							// 上りマッピング処理(異動予約予約適用年月日変更)
							Object[][] ekk1681c040InMsg = {{EKK1681C040CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK1681C040},
															{EKK1681C040CBSMsg.FUNC_CODE, JPCModelConstant.FUNC_CD_1},
															{EKK1681C040CBSMsg.IDO_RSV_NO, ekk1681B001outMsg[0].getString(EKK1681B001CBSMsg1List.IDO_RSV_NO)},
															{EKK1681C040CBSMsg.RSV_APLY_YMD, rsvAplyYmd},
															{EKK1681C040CBSMsg.UPD_DTM_BF, ekk1681B001outMsg[0].getString(EKK1681B001CBSMsg1List.UPD_DTM)}};
							// SC呼出実行
							callSC(handle, scCall, param, fixedText, ekk1681c040InMsg);
						}
					}
				}
			}
		}
	}
	
	/**
	 * 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];
		
		// リターンコード取得
		int returnCode = (Integer)result.get(JCMConstants.RET_CD_INT_KEY);
		
		int templateStatus = msg.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (0 != returnCode)
		{
			templateStatus = 9000;
		}
		
		if (null == JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", 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("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}
		
		setErrorInf(msg, (HashMap<String, Object>)param.getData(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));
		
		/* ◇処理結果の判定*/
		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();
		Integer status = msg.getInt(JCMConstants.STATUS_INT_KEY);
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(rtnCode) && 0 == status.intValue()))
		{
			SCCallException scCallEx = new SCCallException("戻り値不正", rtnCode, status);
			throw scCallEx;
		}
		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 ("".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 inMap
	 * @param templates
	 * @param returnCode
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	private IRequestParameterReadWrite editErrorInfoEKK0341B029(IRequestParameterReadWrite param, 
																HashMap<String, Object> inMap,
																CAANMsg[] templates, 
																int returnCode) throws RequestParameterException
	{
		CAANMsg template = templates[0];
		
		int templateStatus = template.getInt(EKK0341B029CBSMsg.STATUS);
		if (0 != returnCode)
		{
			templateStatus = 9000;
		}
		
		if (null == JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", 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("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}
		
		setErrorInf(template, inMap);
		return param;
	}
	
	/**
	 * エラー情報を設定します。
	 * 
	 * @param msg
	 * @param map
	 * 
	 */
	@SuppressWarnings("unchecked")
	private void setErrorInf(CAANMsg msg, HashMap<String, Object> map)
	{
		Iterator<String> msgKey = msg.getSchema().getSchemaKeySet().iterator();
		
		while (msgKey.hasNext())
		{
			String key = msgKey.next();
			
			if (key.endsWith("_err"))
			{
				if (!msg.isNull(key))
				{
					if (!map.containsKey(key))
					{
						map.put(key, msg.getString(key));
					}
				}
			}
		}
	}
	// ANK-4315-00-00 ADD END
}
