/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKejbKK0351ETDA
*   ソースファイル名：JKKejbKK0351ETDA.java
*   作成者          ：富士通
*   日付            ：2011年11月14日
*＜機能概要＞
*   オプションサービス契約のDBアクセス部品クラス
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/11/14  富士通      新規作成
*   v4.00.00    2013/02/05  FJ)坂本     ST4-2012-0000263
*   v4.00.01    2013/07/15  FJ)竹内     TG1-2013-0000704
*	v5.00.00	2013/10/30	FJ)小島		OM-2013-0002943
*	v6.00.00	2013/11/29	FJ)大山		IT2-2013-0000830
*	v8.00.00	2014/03/11	FJ)寺園		ANK-1855-00-00
*	v7.00.00	2014/03/17	FJ)寺園		OM-2014-0000967
*   v8.00.00	2014/03/24	FJ）松枝	OM-2014-0000286
*   v8.00.01	2014/04/14	FJ)宇野		OM-2014-0001430
*   v8.00.02	2014/04/29	FJ)宇野		OM-2014-0001529、OM-2014-0001536
*   v8.00.03	2014/05/13	FJ)石原		OM-2014-0001781
*   v9.00.00	2014/06/30	FJ)横田		OM-2014-0002226
*	v9.00.01	2014/08/04	FJ)小島		OM-2014-0002598
*	v9.00.02	2014/08/28	FJ)星野		OM-2014-0002752
*	v11.00.00	2014/12/24	FJ)寺園		OM-2014-0003837
*	v12.00.00	2015/02/05	FJ)川島		OM-2015-0000217
*	v12.01.00	2015/03/03	FJ)川島		OM-2014-0004052
*	v39.00.00	2018/10/01	FJ)舘山		ANK-3484-00-00_端末補償サービス導入対応
*	v50.00.00	2020/06/12  FJ)西窪		【ANK-3754-00-00】トビラフォン対応
*   v50.00.01   2020/08/24  FJ)舘山     IT2-2020-0000014_横並び対応
*   v61.00.00   2023/04/21  FJ)新井     ANK-4315-00-00_【eo定期】 eoホームゲートウェイ導入対応
*   v71.00.00	2024/05/13  FJ)舘山		#84334_HGW瑕疵内障害
*	v73.00.00	2024/09/26	FJ)謝		【ANK-4427-00-00】NTT卸対応
*	v75.00.00	2025/05/22	FJ)謝		【#87269】電話サービス（オプション）の開始日が申込日（受付日）基準となる
**********************************************************************/

package eo.ejb.common.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.common.util.JPCDateUtil;
import eo.common.util.JPCUtilCommon;
import eo.ejb.cbm.entity.CH0501ETMsg;
import eo.ejb.cbm.entity.DK0011ETMsg;
import eo.ejb.cbm.entity.KK0011ETMsg;
import eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0161ETMsg;
import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbm.entity.KK0361ETMsg;
import eo.ejb.cbm.entity.KK0401ETMsg;
import eo.ejb.cbm.entity.KK1681ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0081C260CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0351C130CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0351C250CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0361C040CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0381C040CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.entity.JKKejbIdoRsvAccess;
import eo.ejb.common.rule.JKKejbRule0066001;
import eo.ejb.common.rule.JKKejbRule0074001;
import eo.ejb.common.rule.JKKejbRule0083001;
import eo.ejb.common.rule.JKKejbRule0088001;

/**
 * <p>
 * オプションサービス契約のDBアクセス部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbKK0351ETDA
{

	/** スキーマID オプションサービス契約 */
	public static final String SCHEMAID_OPSVCKEI = "KK0351";

	/** スキーマID 異動予約 */
	public static final String SCHEMAID_IDORSV = "KK1681";

	/** エラーフラグ 異動対象スキーマ判定相関ルール */
	public static final String RSLT_CORR_IDORSV = "5";

	/** 契約ステータス サービス提供中 */
	private static final String STAT_USING = "100";

	/** 予約適用コード 予約確定 */
	private static final String APLYCD_DECIDED = "2";

	/** 終了年月日 システム最終年月日 */
	private static final String SYS_LASTYMD = "20991231";

	/** 無効フラグ 有効 */
	private static final String MKFLG_VALID = "0";

	/** 関連チェックエラーフラグ&エラー返却項目(サブオプションサービス契約 開始日確定チェック) */
	private static final String[] KRCK_SBOP_START_DECIDED_ERR = {"EC", EKK0361C040CBSMsg.OP_SVC_KEI_NO_ERR};

	/** 親契約識別コード(サービス契約) */
	private static final String OYA_KEI_SKBT_CD_SVC_KEI = "01";

	/** 親契約識別コード(サービス契約内訳) */
	private static final String OYA_KEI_SKBT_CD_SVC_KEI_UCWK = "03";

	/** オプションサービス.オプションサービスコード(スマートリンクプレミアム) */
	private static final String OP_SVC_CD_SMT_LINK_PRE = "B077";

	/** 異動予約詳細コード オプション開始 */
	private static final String IDO_RSV_DTL_OPSTA = "014";
	
	/** オプションサービス契約番号 */
	private static final String OP_SVC_KEI_NO = "op_svc_kei_no";
	
	/** オプションサービス契約<ISP>開始 */
	private static final String TEMPLATE_ID_EKK0361C040 = "EKK0361C040";

	// OM-2014-0003837 ADD START
	/** 解約時課金フラグ(非課金) */
	private static final String DSLJI_CHRG_FLG_NO_CHRG = "0";

	/** 解約時課金フラグ(課金) */
	private static final String DSLJI_CHRG_FLG_CHRG = "1";
	// OM-2014-0003837 ADD END
// ▽▽▽
	/** 端末補償オプションサービスコードリスト */
	private static List<String> TMCP_OP_SVC_CD_LIST = java.util.Arrays.asList(new String[] {"B133", "B134"});
// △△△
// ▽▽▽ ANK-3754-00-00 ADD STRAT
	/** オプションサービス.オプションサービスコード(あんしん発着信サービス) */
	private static final String OP_SVC_CD_ANSN_HCS_SVC = "B135";
// △△△ ANK-3754-00-00 ADD END
// #87269 ADD START
	/** オプションサービス.オプションサービスコード(eo光電話(type N)) */
	private static final String OP_SVC_CD_TYPEN = "B138";
// #87269 ADD END

	/**
	 * <p>
	 * 新しいJKKejbKK0351ETDAを作成します。
	 * </p>
	 */
	public JKKejbKK0351ETDA()
	{
	}

	/**
	 * <p>
	 * 「オプションサービス契約」のレコードを削除(論理削除)します。
	 * </p>
	 * @param kk0351Msg 削除対象となる「オプションサービス契約」履歴世代レコードのメッセージキャリア
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void deleteKK0351(CAANMsg kk0351Msg, String updDtm, String updOpeAct)
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());

		inETMsg.set(KK0351ETMsg.OP_SVC_KEI_NO, kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_NO));
		inETMsg.set(KK0351ETMsg.GENE_ADD_DTM, kk0351Msg.getString(KK0351ETMsg.GENE_ADD_DTM));
		inETMsg.set(KK0351ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0351ETMsg.UPD_OPEACNT, updOpeAct);
		inETMsg.set(KK0351ETMsg.DEL_DTM, updDtm);
		inETMsg.set(KK0351ETMsg.DEL_OPEACNT, updOpeAct);
		inETMsg.set(KK0351ETMsg.MK_FLG, JKKModelConst.MK_FLG_MK);

		// 更新を行う
		new JKKejbDBAUtil(inETMsg).update(inETMsg);

		// サブタイプ更新を行う
		JKKejbKK0351SubTypeDelete instance = new JKKejbKK0351SubTypeDelete(inETMsg);
		instance.setOpSvcKeiNo(kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_NO));
		instance.setGeneAddDtm(kk0351Msg.getString(KK0351ETMsg.GENE_ADD_DTM));
		instance.setAddUpdDelDtm(updDtm);
		instance.setAddUpdDelOpeacnt(updOpeAct);
		instance.deleteSubTypeKK0351();
	}

	/**
	 * <p>
	 * 開始日設定(オプションサービス)相関ルールを実行します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo	オプションサービス契約番号
	 * @param svcCd		「同時申込」を判定するサービスコード
	 * @param skjYkgt	即時/翌月(01:即時、02:翌月)
	 * @return 相関ルールにより取得した開始日
	 */
	public String execSokanOfStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext,
										String opSvcKeiNo, String svcCd, String skjYkgt)
	{
		// オプションサービス契約に紐付くサービス契約のサービスコードを取得
		CAANMsg kk0081Cur = getCurSvcKeiViaOpKei(inCBSMsg, inContext, opSvcKeiNo);
		
		// オプションサービス契約が存在しない場合
		if (kk0081Cur == null)
		{
			return null;
		}
		String curSvcCd = kk0081Cur.getString(KK0081ETMsg.SVC_CD);
		
		// オプションサービス契約のオプションサービスコードを取得
		CAANMsg kk0351Cur = getCurOpKei(inCBSMsg, inContext, opSvcKeiNo);
		String opSvcCd = kk0351Cur.getString(KK0351ETMsg.OP_SVC_CD);
	
		// OM-2014-0002598 MOD START
		// オプションサービス契約に紐付くサービス契約のサービス開始年月日を取得
		//String svcStaYmd = kk0081Cur.getString(KK0081ETMsg.SVC_STA_YMD);
		String svcStaYmd = null;
		String svcChrgStaymd = null;
		
		// サービスが電話の場合
		if (JKKModelConst.SVC_CD_TEL.equals(svcCd))
		{
			// サービス契約内訳番号に紐付くサービス契約内訳を取得
			CAANMsg kk0161Cur = getCurSvcKeiUcwk(inCBSMsg, inContext, kk0351Cur.getString(KK0351ETMsg.SVC_KEI_UCWK_NO));
			
			// オプションサービス契約に紐付くサービス契約内訳のサービス開始年月日を取得
			svcStaYmd = kk0161Cur.getString(KK0161ETMsg.SVC_STA_YMD);
			
			// オプションサービス契約に紐付くサービス契約内訳のサービス課金開始年月日を取得
			svcChrgStaymd = kk0161Cur.getString(KK0161ETMsg.SVC_CHRG_STAYMD);
		}
		else
		{
			// オプションサービス契約に紐付くサービス契約のサービス開始年月日を取得
			svcStaYmd = kk0081Cur.getString(KK0081ETMsg.SVC_STA_YMD);
			
			// オプションサービス契約に紐付くサービス契約のサービス課金開始年月日を取得
			svcChrgStaymd = kk0081Cur.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
		}
		// OM-2014-0002598 MOD END
		
		// サービス契約のサービス開始年月日が未設定の場合
		if (svcStaYmd == null)
		{
			// 異動予約より予約適用年月日を取得する
			JKKejbIdoRsvAccess jkIdoAc = new JKKejbIdoRsvAccess();
			List<CAANMsg> kk1681IdoList = jkIdoAc.getIdoRsvSvcKeiNo(kk0081Cur.getString(KK0081ETMsg.SVC_KEI_NO), JKKModelCommon.getOpeDate(inCBSMsg));

			for (CAANMsg msg : kk1681IdoList)
			{
				// 異動予約詳細コードがオプション開始か判定
				if (IDO_RSV_DTL_OPSTA.equals(msg.getString(KK1681ETMsg.IDO_RSV_DTL_CD)))
				{
					// 異動予約の予約適用年月日を設定
					svcStaYmd = msg.getString(KK1681ETMsg.RSV_APLY_YMD);
				}
			}
		}
		
		// オプションサービス契約に紐付く申込の申込受付年月日時分秒を取得し、年月日形式に変換
		CAANMsg kk0011Cur = getCurMskmViaOpKei(inCBSMsg, inContext, opSvcKeiNo);
		String mskmUkDtm = kk0011Cur.getString(KK0011ETMsg.MSKM_UK_DTM);
		String mskmUkYmd = JKKModelCommon.toYmdFromDtm(mskmUkDtm);
		
		// オプションサービス契約のサービス利用開始希望年月日を取得
		String svcUseStaKiboYmd = kk0351Cur.getString(KK0351ETMsg.SVC_USE_STA_KIBO_YMD);
// #87269 ADD START
		// eo光電話(type N)の場合
		if (OP_SVC_CD_TYPEN.equals(opSvcCd))
		{
			if (inCBSMsg.containsKeyOfSchema(EKK0361C040CBSMsg.DSP_SVCTK_STAYMD))
			{
				// サービス利用開始希望年月日に表示用サービス提供開始年月日を設定
				svcUseStaKiboYmd = inCBSMsg.getString(EKK0361C040CBSMsg.DSP_SVCTK_STAYMD);
			}
		}
// #87269 ADD END
		
		// 申込明細の申込年月日を取得
		CAANMsg kk0021Cur = this.getCurMskmDtl(inCBSMsg, inContext, kk0351Cur.getString(KK0351ETMsg.MSKM_DTL_NO));
		String mskmYmd = kk0021Cur.getString(KK0021ETMsg.MSKM_YMD);

		// OM-2014-0002598 DEL START
		// オプションサービス契約に紐付くサービス契約のサービス課金開始年月日を取得
		//String svcChrgStaymd = kk0081Cur.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
		// OM-2014-0002598 DEL END
		
		// 申込期間を取得する
		String mskmPeriod = this.getMskmPeriod(inCBSMsg, mskmYmd, svcStaYmd, svcChrgStaymd);
		// 申込期間が未設定または期間未定の場合はnullを返却（関連制約エラーとする）
		if (mskmPeriod == null || "0".equals(mskmPeriod))
		{
			return null;
		}
		
		// 元のサービス契約の料金グループコードを取得する
		String prcGrpCd = kk0081Cur.getString(KK0081ETMsg.PRC_GRP_CD);

// ▽▽▽ ANK-3484-00-00 ADD START
		String tmcpMskmYmd = null;
		if (TMCP_OP_SVC_CD_LIST.contains(opSvcCd))
		{
			CAANMsg kk0361Cur = getCurOpKeiIsp(inCBSMsg, inContext, opSvcKeiNo);
			tmcpMskmYmd = kk0361Cur.getString(KK0361ETMsg.TMCP_MSKM_YMD);
		}
// △△△ ANK-3484-00-00 ADD END

		// 相関ルールのパラメータを設定
		JKKejbRule0074001 rule0074001 = new JKKejbRule0074001(inCBSMsg);
		rule0074001.setSvc_cd(curSvcCd);
		rule0074001.setOp_svc_cd(opSvcCd);
		rule0074001.setMskm_period(mskmPeriod);
		rule0074001.setSkj_ykjt(skjYkgt);
		rule0074001.setKk0081_svc_sta_ymd(svcStaYmd);
		rule0074001.setKk0011_mskm_uk_ymd(mskmUkYmd);
		rule0074001.setSvc_use_sta_kibo_ymd(svcUseStaKiboYmd);

		// 元のサービス契約の料金グループコードを設定する
		rule0074001.setKk0081_prc_grp_cd(prcGrpCd);

// ▽▽▽ ANK-3484-00-00 ADD START
		rule0074001.setKk0081_svc_chrg_sta_ymd(svcChrgStaymd);
		rule0074001.setTmcp_mskm_ymd(tmcpMskmYmd);
// △△△ ANK-3484-00-00 ADD END

		// 入力値「サービス開始年月日」（オプションサービス契約<TV>開始）の項目を保持する場合、
		// 相関ルールパラメータに設定する
		if (inCBSMsg.containsKeyOfSchema(EKK0381C040CBSMsg.SVC_STAYMD))
		{
			rule0074001.setInput_svc_sta_ymd(inCBSMsg.getString(EKK0381C040CBSMsg.SVC_STAYMD));
		}
		
		// 異動区分を設定する
		rule0074001.setIdo_kbn(inCBSMsg.getString(EKK0361C040CBSMsg.IDO_DIV));

		// オプションサービス契約のオプションサービスコードが「スマートリンクプレミアム」オプションの場合
		if (OP_SVC_CD_SMT_LINK_PRE.equals(opSvcCd))
		{
			// 料金計算日より求めた請求年月の末日を取得
			String ch0501SeikyYmd = this.getCH0501SeikyYmd(inCBSMsg, inContext);
			// 料金計算日より求めた請求年月の末日を設定します
			rule0074001.setCh0501_seiky_ymd(ch0501SeikyYmd);

			// 関連機器出荷完了日+10日を取得する
			String knrKikiSyukaKnrDay = this.getDK0011HaisoFinYmd(kk0081Cur, inContext);
			// 関連機器出荷完了日+10日を設定します
			rule0074001.setDk0011_Haiso_Fin_Ymd_Add10(knrKikiSyukaKnrDay);
		}

		// ▽▽▽ ANK-3754-00-00 ADD STRAT
		// オプションサービス契約のオプションサービスコードが「あんしん発着信サービス」オプションの場合
		if (OP_SVC_CD_ANSN_HCS_SVC.equals(opSvcCd))
		{
			// 多機能ルーターの工事会社配送コード、出荷日、工事完了日を取得する
			HashMap<String, Object> tknuinfo = this.getTknuinfo(inCBSMsg, inContext, kk0081Cur);
			if(null != tknuinfo)
			{
				String knrKikiSyukaKnrDay = (String) tknuinfo.get("HAISO_FIN_YMD");
				String hisos_kocomp_cd = (String) tknuinfo.get("HISOS_KOCOMP_CD");
				String kojiKnrDay = (String) tknuinfo.get("KOJIAK_JSSI_YMD");
				
				// 関連機器出荷完了日+10日を設定します
				rule0074001.setDk0011_Haiso_Fin_Ymd_Add10(knrKikiSyukaKnrDay);
				// 工事会社配送フラグを設定します
				if(hisos_kocomp_cd != null && !"".equals(hisos_kocomp_cd)){
					rule0074001.setKochai_flg("2");
				}else{
					rule0074001.setKochai_flg("");
				}
				// 工事完了日を設定します
				rule0074001.setKojiak_jssi_ymd(kojiKnrDay);
			}
		}
		// △△△ ANK-3754-00-00 ADD END

		// 開始日設定(オプションサービス)相関ルールを呼出
		String staYmd = rule0074001.getStaYmd();
		
		return staYmd;
	}

// OM-2014-0004052 2015/03/03 ADD START
	/**
	 * <p>
	 * 課金開始日設定(オプション)相関ルールを実行します。<br>
	 * (オプション引継以外の場合、こちらを使用する)
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo	オプションサービス契約番号
	 * @param skjYkgt	即時/翌月(01:即時、02:翌月)
	 * @param staYmd	開始日設定(オプションサービス)相関ルールで算出した開始年月日
	 * @return 相関ルールにより取得した課金開始日
	 */
	public String execSokanOfChrgStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext,
											String opSvcKeiNo, String skjYkgt, String staYmd)
	{
		return execSokanOfChrgStaYmd(inCBSMsg, inContext, opSvcKeiNo, skjYkgt, staYmd, null);
	}
// OM-2014-0004052 2015/03/03 ADD END

	/**
	 * <p>
	 * 課金開始日設定(オプション)相関ルールを実行します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo	オプションサービス契約番号
	 * @param skjYkgt	即時/翌月(01:即時、02:翌月)
	 * @param staYmd	開始日設定(オプションサービス)相関ルールで算出した開始年月日
	 * @param opHktgiYmd	オプション引継年月日
	 * @return 相関ルールにより取得した課金開始日
	 */
// OM-2014-0004052 2015/03/03 MOD START
//	public String execSokanOfChrgStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext,
//											String opSvcKeiNo, String skjYkgt, String staYmd)
	public String execSokanOfChrgStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext,
											String opSvcKeiNo, String skjYkgt, String staYmd, String opHktgiYmd)
// OM-2014-0004052 2015/03/03 MOD END
	{
		// オプションサービス契約に紐付くサービス契約のサービスコードを取得
		CAANMsg kk0081Cur = getCurSvcKeiViaOpKei(inCBSMsg, inContext, opSvcKeiNo);
		String curSvcCd = kk0081Cur.getString(KK0081ETMsg.SVC_CD);
		
		// オプションサービス契約のオプションサービスコードを取得
		CAANMsg kk0351Cur = getCurOpKei(inCBSMsg, inContext, opSvcKeiNo);
		String opSvcCd = kk0351Cur.getString(KK0351ETMsg.OP_SVC_CD);
		
		// OM-2014-0002598 MOD START
		// オプションサービス契約に紐付くサービス契約のサービス開始年月日を取得
		//String svcStaYmd = kk0081Cur.getString(KK0081ETMsg.SVC_STA_YMD);
		String svcStaYmd = null;
		String svcChrgStaymd = null;
		
		// サービスが電話の場合
		if (JKKModelConst.SVC_CD_TEL.equals(curSvcCd))
		{
			// サービス契約内訳番号に紐付くサービス契約内訳を取得
			CAANMsg kk0161Cur = getCurSvcKeiUcwk(inCBSMsg, inContext, kk0351Cur.getString(KK0351ETMsg.SVC_KEI_UCWK_NO));
			
			// オプションサービス契約に紐付くサービス契約内訳のサービス開始年月日を取得
			svcStaYmd = kk0161Cur.getString(KK0161ETMsg.SVC_STA_YMD);
			
			// オプションサービス契約に紐付くサービス契約内訳のサービス課金開始年月日を取得
			svcChrgStaymd = kk0161Cur.getString(KK0161ETMsg.SVC_CHRG_STAYMD);
		}
		else
		{
			// オプションサービス契約に紐付くサービス契約のサービス開始年月日を取得
			svcStaYmd = kk0081Cur.getString(KK0081ETMsg.SVC_STA_YMD);
			
			// オプションサービス契約に紐付くサービス契約のサービス課金開始年月日を取得
			svcChrgStaymd = kk0081Cur.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
		}
		// OM-2014-0002598 MOD END
		
		// サービス契約のサービス開始年月日が未設定の場合
		if (svcStaYmd == null)
		{
			// 異動予約より予約適用年月日を取得する
			JKKejbIdoRsvAccess jkIdoAc = new JKKejbIdoRsvAccess();
			List<CAANMsg> kk1681IdoList = jkIdoAc.getIdoRsvSvcKeiNo(kk0081Cur.getString(KK0081ETMsg.SVC_KEI_NO), JKKModelCommon.getOpeDate(inCBSMsg));

			for (CAANMsg msg : kk1681IdoList)
			{
				// 異動予約詳細コードがオプション開始か判定
				if (IDO_RSV_DTL_OPSTA.equals(msg.getString(KK1681ETMsg.IDO_RSV_DTL_CD)))
				{
					// 異動予約の予約適用年月日を設定
					svcStaYmd = msg.getString(KK1681ETMsg.RSV_APLY_YMD);
				}
			}
		}

		// 申込明細の申込年月日を取得
		CAANMsg kk0021Cur = this.getCurMskmDtl(inCBSMsg, inContext, kk0351Cur.getString(KK0351ETMsg.MSKM_DTL_NO));
		String mskmYmd = kk0021Cur.getString(KK0021ETMsg.MSKM_YMD);

		// OM-2014-0002598 DEL START
		// オプションサービス契約に紐付くサービス契約のサービス課金開始年月日を取得
		//String svcChrgStaymd = kk0081Cur.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
		// OM-2014-0002598 DEL END

		// 申込期間を取得する
		String mskmPeriod = this.getMskmPeriod(inCBSMsg, mskmYmd, svcStaYmd, svcChrgStaymd);
		// 申込期間が未設定または期間未定の場合はnullを返却（関連制約エラーとする）
		if (mskmPeriod == null || "0".equals(mskmPeriod))
		{
			return null;
		}

		// オプションサービス契約に紐付くサービス契約の料金グループを取得
		String prcGrpCd = kk0081Cur.getString(KK0081ETMsg.PRC_GRP_CD);

// ▽▽▽ ANK-3484-00-00 ADD END
		// 引継元の課金終了日を取得する。
		// 端末補償では、端末補償契約番号がユニークに設定されるためその情報をキーとして取得する。
		// その他のオプションでは引継元の課金終了日は使わないためnullを設定する
		String prvChrgEndYmd = getTmcpPreviousSvcChrgEnd(kk0351Cur, inContext, kk0351Cur.getString(KK0351ETMsg.OP_SVC_KEI_NO), opSvcCd);
// △△△ ANK-3484-00-00 ADD END
		
		// OM-2014-0004052 2015/03/03 ADD START
		// オプション引継年月日が設定されている時、課金開始日と比較を行い、
		// 課金開始日 ＜ オプション引継年月日の場合、オプション引継年月日を課金開始日として、
		// RULE0066に連携する。
		String bfSvcChrgStaYmd = svcChrgStaymd;
		if(null != opHktgiYmd && null != bfSvcChrgStaYmd)
		{
			if(bfSvcChrgStaYmd.compareTo(opHktgiYmd) < 0)
			{
				bfSvcChrgStaYmd = opHktgiYmd;
			}
		}
		// OM-2014-0004052 2015/03/03 ADD END
		
		JKKejbRule0066001 rule0066001 = new JKKejbRule0066001(inCBSMsg);
		rule0066001.setSvc_cd(curSvcCd);
		rule0066001.setIdo_div(inCBSMsg.getString("ido_div")); // 異動区分を設定する
		rule0066001.setUpd_type("1"); // 更新契機(開始時)を設定する
		rule0066001.setOp_svc_cd(opSvcCd);
		rule0066001.setSvc_sta_ymd(staYmd);
// OM-2014-0004052 2015/03/03 MOD START
//		rule0066001.setBefor_svc_chrg_sta_ymd(svcChrgStaymd);
		rule0066001.setBefor_svc_chrg_sta_ymd(bfSvcChrgStaYmd);
// OM-2014-0004052 2015/03/03 MOD END
		rule0066001.setMskm_period(mskmPeriod);
		rule0066001.setPrc_grp_cd(prcGrpCd);
// ▽▽▽ ANK-3484-00-00 ADD END
		// 引継元の課金終了日
		rule0066001.setBefor_svc_chrg_end_ymd(prvChrgEndYmd);
// △△△ ANK-3484-00-00 ADD END
		
		// オプションサービス契約のオプションサービスコードが「スマートリンクプレミアム」オプションの場合
		if (OP_SVC_CD_SMT_LINK_PRE.equals(opSvcCd))
		{
			// 料金計算日より求めた請求年月の末日を取得
			String ch0501SeikyYmd = this.getCH0501SeikyYmd(inCBSMsg, inContext);
			// 請求年月の末日が取得できなかった場合nullを返却
			if (ch0501SeikyYmd == null)
			{
				return null;
			}
			
			// 請求年月の末日以前／以降を設定する
			if (svcChrgStaymd != null)
			{
				// 元のサービス契約のサービス課金開始年月日＜＝料金計算日より求めた請求年月の末日
				if (svcChrgStaymd.compareTo(ch0501SeikyYmd) <= 0)
				{
					rule0066001.setSeikyu_Ym_Zengo("1");
				}
				else
				{
					rule0066001.setSeikyu_Ym_Zengo("0");
				}
			}
		}
		
		// 課金開始日設定(オプションサービス)相関ルールを呼出
		String chrgStaYmd = rule0066001.getChrgStaYmd();
		
		return chrgStaYmd;
	}

	/**
	 * <p>
	 * 異動対象スキーマ判定相関ルールを実行します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcStaYmd		開始日設定(オプションサービス)相関ルールで算出したサービス開始年月日
	 * @return 異動対象スキーマ判定相関ルール実行結果のリスト
	 */
	public List<HashMap<String, Object>> execSokanOfIdoJdg(CAANMsg inCBSMsg, AgentDispatchContext inContext, String svcStaYmd)
	{
		String opeDate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		// 相関ルールにて振舞うスキーマを判定
		JKKejbRule0083001 rule0083 = new JKKejbRule0083001(inCBSMsg);
		rule0083.setSvc_if_id(inCBSMsg.getString(JCMConstants.TEMPLATE_ID_KEY));
		rule0083.setBase_date(svcStaYmd);
		rule0083.setOpe_date(opeDate);
		
		List<HashMap<String, Object>> ruleList = rule0083.referRuleEngine();
		
		return ruleList;
	}

	/**
	 * <p>
	 * 異動対象スキーマ判定相関ルールの結果を元に振舞うスキーマを判定します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param ruleList　異動対象スキーマ判定相関ルール実行結果のリスト
	 * @return 振舞対象スキーマ
	 */
	public String judgeSchema(CAANMsg inCBSMsg, AgentDispatchContext inContext, List<HashMap<String, Object>> ruleList)
	{
		String ret = null;
		
		for (HashMap<String, Object> hm : ruleList)
		{
			if (SCHEMAID_OPSVCKEI.equals(hm.get(JKKejbRule0083001.TRGT_SCHEMA_ID)))
			{
				ret = SCHEMAID_OPSVCKEI;
			}
			if (SCHEMAID_IDORSV.equals(hm.get(JKKejbRule0083001.TRGT_SCHEMA_ID)))
			{
				ret = SCHEMAID_IDORSV; 
			}
		}
		
		return ret;
	}

	/**
	 * <p>
	 * オプションサービス契約への振舞を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0351Msg　オプションサービス契約のETメッセージ
	 * @param staYmd　開始年月日
	 * @param chrgStaYmd　課金開始年月日
	 * @return オプションサービス契約に登録した内容を持ったETメッセージ
	 */
	public CAANMsg execDBAccessOpKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0351Msg,
											String staYmd, String chrgStaYmd)
	{
		CAANMsg dbInfo = setInfoOfOpKei(inCBSMsg, inContext, kk0351Msg, staYmd, chrgStaYmd);
		
		createKK0351(inCBSMsg, inContext, dbInfo);

		return dbInfo;
	}

	/**
	 * <p>
	 * 異動予約への振舞を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk1681Msg　異動予約のETメッセージ
	 * @param staYmd　開始年月日
	 * @param chrgStaYmd　課金開始年月日
	 * @param ruleMap 異動対象スキーマ判定相関ルールの結果のマップ
	 * @return 異動予約に登録した内容を持ったETメッセージ
	 */
	public CAANMsg execDBAccessIdoRsv(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk1681Msg,
										String staYmd, String chrgStaYmd, Map<String, Object> ruleMap)
	{
		CAANMsg dbInfo = setInfoOfIdoRsv(inCBSMsg, inContext, kk1681Msg, staYmd, chrgStaYmd, ruleMap);
		
		createKK1681(inCBSMsg, inContext, dbInfo);
		
		return dbInfo;
	}
	
	/**
	 * <p>
	 * 異動予約への振舞を行います（副次処理用）。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param msgKK0401　副次対象のサブオプションサービス契約レコード
	 * @param ruleMap 異動対象スキーマ判定相関ルールの結果のマップ
	 * @return 異動予約に登録した内容を持ったETメッセージ
	 */
	public void execDBAccessIdoRsvSec(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg msgKK0401, Map<String, Object> ruleMap)
	{
		String opSvcKeiNo = msgKK0401.getString(KK0401ETMsg.OP_SVC_KEI_NO);
		String sbopSvcKeiNo = msgKK0401.getString(KK0401ETMsg.SBOP_SVC_KEI_NO);
		String skjYkgt = inCBSMsg.getString(EKK0361C040CBSMsg.SKJ_YKGT);

		// サブオプションサービス契約ETDA生成
		JKKejbKK0401ETDA sbopEtda = new JKKejbKK0401ETDA();

		// 開始日設定(サブオプションサービス)相関ルール
		String staYmd = sbopEtda.execSokanOfStaYmd(inCBSMsg, inContext, opSvcKeiNo, sbopSvcKeiNo, skjYkgt);

		if (null == staYmd)
		{
			// 開始日を取得しなかった場合、関連チェックエラー
			setErrInfo(inCBSMsg, StatusCodes.RELATION_ERR, KRCK_SBOP_START_DECIDED_ERR);
			return;
		}

		CAANMsg dbInfo = setInfoOfIdoRsvSec(inCBSMsg, inContext, msgKK0401, staYmd, ruleMap);

		createKK1681(inCBSMsg, inContext, dbInfo);
	}

	/**
	 * <p>
	 * 申込明細のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param mskmDtlNo 申込明細番号
	 * @return 申込明細のカレントレコード
	 */
	private CAANMsg getCurMskmDtl(CAANMsg inCBSMsg, AgentDispatchContext inContext, String mskmDtlNo)
	{
		CAANMsg kk0021Cond = new CAANMsg(KK0021ETMsg.class.getName());
		kk0021Cond.set(KK0021ETMsg.MSKM_DTL_NO, mskmDtlNo);
		
		return new JKKejbKK0021DBABase().findByCurrent(kk0021Cond);
	}

	/**
	 * <p>
	 * 申込のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param mskmNo 申込番号
	 * @return 申込のカレントレコード
	 */
	private CAANMsg getCurMskm(CAANMsg inCBSMsg, AgentDispatchContext inContext, String mskmNo)
	{
		CAANMsg kk0011Cond = new CAANMsg(KK0011ETMsg.class.getName());
		kk0011Cond.set(KK0011ETMsg.MSKM_NO, mskmNo);
		
		return new JKKejbKK0011DBABase().findByCurrent(kk0011Cond);
	}

	/**
	 * <p>
	 * オプションサービス契約に紐付く申込のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約に紐付く申込のカレントレコード
	 */
	private CAANMsg getCurMskmViaOpKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, String opSvcKeiNo)
	{
		// オプションサービス契約のカレントレコードを取得
		CAANMsg kk0351Cur = getCurOpKei(inCBSMsg, inContext, opSvcKeiNo);
		
		String mskmDtlNo = kk0351Cur.getString(KK0351ETMsg.MSKM_DTL_NO);
		
		// 申込明細のカレントレコードを取得
		CAANMsg kk0021Cur = getCurMskmDtl(inCBSMsg, inContext, mskmDtlNo);
		
		String mskmNo = kk0021Cur.getString(KK0021ETMsg.MSKM_NO);

		// 申込のカレントレコードを取得
		CAANMsg kk0011Cur = getCurMskm(inCBSMsg, inContext, mskmNo);
		
		return kk0011Cur;
	}

	/**
	 * <p>
	 * オプションサービス契約のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約のカレントレコード
	 */
	private CAANMsg getCurOpKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, String opSvcKeiNo)
	{
		String opeDate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		CAANMsg kk0351Cond = new CAANMsg(KK0351ETMsg.class.getName());
		kk0351Cond.set(KK0351ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		kk0351Cond.set(KK0351ETMsg.RSV_APLY_YMD, opeDate);
		
		return new JKKejbKK0351DBABase().findByCurrent(kk0351Cond);
	}

	/**
	 * <p>
	 * サービス契約のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo	サービス契約番号
	 * @return サービス契約のカレントレコード
	 */
	private CAANMsg getCurSvcKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, String svcKeiNo)
	{
		String opeDate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		CAANMsg kk0081Cond = new CAANMsg(KK0081ETMsg.class.getName());
		kk0081Cond.set(KK0351ETMsg.SVC_KEI_NO, svcKeiNo);
		kk0081Cond.set(KK0351ETMsg.RSV_APLY_YMD, opeDate);
		
		return new JKKejbKK0081DBABase().findByCurrent(kk0081Cond);
	}

	/**
	 * <p>
	 * サービス契約内訳のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo	サービス契約内訳番号
	 * @return サービス契約内訳のカレントレコード
	 */
	private CAANMsg getCurSvcKeiUcwk(CAANMsg inCBSMsg, AgentDispatchContext inContext, String svcKeiUcwkNo)
	{
		CAANMsg kk0161Cond = new CAANMsg(KK0161ETMsg.class.getName());
		kk0161Cond.set(KK0161ETMsg.SVC_KEI_UCWK_NO, svcKeiUcwkNo);
		kk0161Cond.set(KK0161ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		return new JKKejbKK0161DBABase().findByCurrent(kk0161Cond);
	}

	/**
	 * <p>
	 * オプションサービス契約に紐付くサービス契約のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約に紐付くサービス契約のカレントレコード
	 */
	private CAANMsg getCurSvcKeiViaOpKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, String opSvcKeiNo)
	{
		// オプションサービス契約のカレントレコードを取得
		CAANMsg kk0351Cur = getCurOpKei(inCBSMsg, inContext, opSvcKeiNo);
		
		// オプションサービス契約が存在しない場合
		if (kk0351Cur == null)
		{
			return null;
		}

		String svcKeiNo = null;
		
		// 親契約識別コードがサービス契約の場合
		if (OYA_KEI_SKBT_CD_SVC_KEI.equals(kk0351Cur.getString(KK0351ETMsg.OYA_KEI_SKBT_CD)))
		{
			// サービス契約番号を使用する
			svcKeiNo = kk0351Cur.getString(KK0351ETMsg.SVC_KEI_NO);
		}
		// 親契約識別コードがサービス契約内訳の場合
		else if (OYA_KEI_SKBT_CD_SVC_KEI_UCWK.equals(kk0351Cur.getString(KK0351ETMsg.OYA_KEI_SKBT_CD)))
		{
			// サービス契約内訳番号に紐付くサービス契約内訳を取得
			CAANMsg retMsgKK0161 = getCurSvcKeiUcwk(inCBSMsg, inContext, kk0351Cur.getString(KK0351ETMsg.SVC_KEI_UCWK_NO));
			
			// 取得したサービス契約内訳のサービス契約番号を使用する
			svcKeiNo = retMsgKK0161.getString(KK0161ETMsg.SVC_KEI_NO);
		}

		// サービス契約カレントレコード検索
		return getCurSvcKei(inCBSMsg, inContext, svcKeiNo);
	}

	/**
	 * <p>
	 * オプションサービス契約の開始に伴うオプションサービス契約の登録内容の設定を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0351Msg　オプションサービス契約のETメッセージ
	 * @param staYmd　開始年月日
	 * @param chrgStaYmd　課金開始年月日
	 * @return オプションサービス契約の登録内容
	 */
	private CAANMsg setInfoOfOpKei(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0351Msg,
									String staYmd, String chrgStaYmd)
	{
		String opSvcKeiNo = kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_NO);
		// サービスインターフェイスID
		String templateID = inCBSMsg.getString(JCMConstants.TEMPLATE_ID_KEY);

		// 引継元となるオプションサービス契約カレントレコード取得
		CAANMsg ret = getCurOpKei(inCBSMsg, inContext, opSvcKeiNo);
		
		// 入力値設定
		ret.set(KK0351ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		ret.set(KK0351ETMsg.GENE_ADD_DTM, JKKModelCommon.getTransferGeneAddDtm(inCBSMsg, inContext));
		ret.set(KK0351ETMsg.OP_SVC_KEI_STAT, STAT_USING);
		String opedate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		//オプションサービス契約ステータスに応じてカレント引継を行うか判定する
		if(JKKModelCommon.isStatCurrentKK0351(inCBSMsg, inContext, inCBSMsg.getObject(OP_SVC_KEI_NO))){
			
			// 運用日 ＞ サービス開始年月日の場合
			if (JPCUtilCommon.isPastDate(staYmd, opedate, "0"))
			{
				ret.set(KK0351ETMsg.RSV_APLY_YMD, opedate);
			}
			else
			{
				ret.set(KK0351ETMsg.RSV_APLY_YMD, staYmd);
			}
		}
		ret.set(KK0351ETMsg.RSV_APLY_CD, APLYCD_DECIDED);
		ret.set(KK0351ETMsg.PLAN_STAYMD, staYmd);
		ret.set(KK0351ETMsg.PLAN_ENDYMD, SYS_LASTYMD);
		ret.set(KK0351ETMsg.PLAN_CHRG_STAYMD, chrgStaYmd);
		ret.set(KK0351ETMsg.PLAN_CHRG_ENDYMD, SYS_LASTYMD);
		ret.set(KK0351ETMsg.SVC_STAYMD, staYmd);

		if ("EKK0381C040".equals(templateID))
        {
			// "EKK0381C040"の場合、「表示用サービス提供開始年月日」には常に「サービス開始年月日」を設定
			ret.set(KK0351ETMsg.DSP_SVCTK_STAYMD, staYmd);
        }
// ANK-4427-00-00 ADD START
		else if ("EKK0361C040".equals(templateID))
		{
			// 表示用サービス提供開始年月日
			String dspSvctkStaymd = kk0351Msg.getString(KK0351ETMsg.DSP_SVCTK_STAYMD);
			if (dspSvctkStaymd != null && dspSvctkStaymd.length() > 0)
			{
				ret.set(KK0351ETMsg.DSP_SVCTK_STAYMD, dspSvctkStaymd);
			}
		}
// ANK-4427-00-00 ADD END

		ret.set(KK0351ETMsg.SVC_CHRG_STAYMD, chrgStaYmd);
		ret.set(KK0351ETMsg.SVC_ENDYMD, SYS_LASTYMD);
		ret.set(KK0351ETMsg.SVC_CHRG_ENDYMD, SYS_LASTYMD);
		ret.set(KK0351ETMsg.IDO_DIV, kk0351Msg.getString(KK0351ETMsg.IDO_DIV));
		ret.set(KK0351ETMsg.ADD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK0351ETMsg.ADD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.set(KK0351ETMsg.UPD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK0351ETMsg.UPD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.setNull(KK0351ETMsg.DEL_DTM);
		ret.setNull(KK0351ETMsg.DEL_OPEACNT);
		ret.set(KK0351ETMsg.MK_FLG, MKFLG_VALID);
		
		return ret;
	}

	/**
	 * <p>
	 * オプションサービス契約の開始に伴う異動予約の登録内容の設定を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk1681Msg　異動予約のETメッセージ
	 * @param staYmd　開始年月日
	 * @param chrgStaYmd　課金開始年月日
	 * @param ruleMap 異動対象スキーマ判定相関ルールの結果のマップ
	 * @return 異動予約の登録内容
	 */
	private CAANMsg setInfoOfIdoRsv(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk1681Msg,
										String staYmd, String chrgStaYmd, Map<String, Object> ruleMap)
	{
		CAANMsg ret = new CAANMsg(KK1681ETMsg.class.getName());
		
		// 相関ルールの設定値を取得
		String idoRsvDtlCd = (String)ruleMap.get(JKKejbRule0083001.IDO_RSV_DTL_CD);
		String idoRsvStatCd = (String)ruleMap.get(JKKejbRule0083001.IDO_RSV_STAT_CD);

		// オプションサービス契約のカレントレコードを取得
		CAANMsg kk0351Cur = getCurOpKei(inCBSMsg, inContext, kk1681Msg.getString(KK1681ETMsg.OP_SVC_KEI_NO));

		// 登録内容設定
		ret.set(KK1681ETMsg.IDO_RSV_NO, JKKModelCommon.getIdoRsvNoKK1681(inCBSMsg, inContext));
		ret.set(KK1681ETMsg.IDO_DIV, kk1681Msg.getString(KK1681ETMsg.IDO_DIV));
		ret.set(KK1681ETMsg.IDO_RSV_DTL_CD, idoRsvDtlCd);
		ret.set(KK1681ETMsg.RSV_APLY_YMD, staYmd);
		ret.set(KK1681ETMsg.IDO_RSV_STAT_CD, idoRsvStatCd);
		ret.set(KK1681ETMsg.MSKM_DTL_NO, kk0351Cur.getString(KK0351ETMsg.MSKM_DTL_NO));
		ret.set(KK1681ETMsg.OP_SVC_KEI_NO, kk1681Msg.getString(KK0351ETMsg.OP_SVC_KEI_NO));

		// Input．オプション引継先サービス契約番号が存在している場合
		if (kk1681Msg.containsKeyOfMsgData(KK1681ETMsg.OP_HKTGI_SK_SVC_KEI_NO))
		{
			// Input．オプション引継先サービス契約番号を設定
			ret.set(KK1681ETMsg.OP_HKTGI_SK_SVC_KEI_NO, kk1681Msg.getString(KK1681ETMsg.OP_HKTGI_SK_SVC_KEI_NO));
		}
		ret.set(KK1681ETMsg.ADD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK1681ETMsg.ADD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.set(KK1681ETMsg.UPD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK1681ETMsg.UPD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.set(KK1681ETMsg.MK_FLG, MKFLG_VALID);
		
		return ret;
	}

	/**
	 * <p>
	 * オプションサービス契約の開始に伴う異動予約の登録内容の設定を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param msgKK0401　副次対象のサブオプションサービス契約レコード
	 * @param staYmd　開始年月日
	 * @param ruleMap 異動対象スキーマ判定相関ルールの結果のマップ
	 * @return 異動予約の登録内容
	 */
	private CAANMsg setInfoOfIdoRsvSec(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg msgKK0401,
										String staYmd, Map<String, Object> ruleMap)
	{
		CAANMsg ret = new CAANMsg(KK1681ETMsg.class.getName());

		// 相関ルールの設定値を取得
		String idoRsvDtlCd = (String)ruleMap.get(JKKejbRule0083001.IDO_RSV_DTL_CD);
		String idoRsvStatCd = (String)ruleMap.get(JKKejbRule0083001.IDO_RSV_STAT_CD);

		// 登録内容設定
		ret.set(KK1681ETMsg.IDO_RSV_NO, JKKModelCommon.getIdoRsvNoKK1681(inCBSMsg, inContext));
		ret.set(KK1681ETMsg.IDO_DIV, inCBSMsg.getString(EKK0361C040CBSMsg.IDO_DIV));
		ret.set(KK1681ETMsg.IDO_RSV_DTL_CD, idoRsvDtlCd);
		ret.set(KK1681ETMsg.RSV_APLY_YMD, staYmd);
		ret.set(KK1681ETMsg.IDO_RSV_STAT_CD, idoRsvStatCd);
		ret.set(KK1681ETMsg.SBOP_SVC_KEI_NO, msgKK0401.getString(KK0401ETMsg.SBOP_SVC_KEI_NO));

		// Input．オプション引継先サービス契約番号が存在している場合
		if (!inCBSMsg.isNull(EKK0361C040CBSMsg.OP_HKTGI_SK_SVC_KEI_NO))
		{
			// Input．オプション引継先サービス契約番号を設定
			ret.set(KK1681ETMsg.OP_HKTGI_SK_SVC_KEI_NO, inCBSMsg.getString(EKK0361C040CBSMsg.OP_HKTGI_SK_SVC_KEI_NO));
		}

		ret.set(KK1681ETMsg.ADD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK1681ETMsg.ADD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.set(KK1681ETMsg.UPD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		ret.set(KK1681ETMsg.UPD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		ret.set(KK1681ETMsg.MK_FLG, MKFLG_VALID);

		return ret;
	}

	/**
	 * <p>
	 * 料金計算日より求めた請求年月に末日を付与して返却します
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 請求年月の末日
	 * </p>
	 */
	private String getCH0501SeikyYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0501ETMsg.getTableName());
			
			
			String templateID = inCBSMsg.getString(JCMConstants.TEMPLATE_ID_KEY);

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("     CH0501.SEIKY_YM AS SEIKY_YM ")
					.append(" FROM ")
					.append("     CH_M_PRC_SCHDL_TEIGI CH0501 ")
					.append(" WHERE ")
					.append("         CH0501.EVENT_CD = '03' ")
					.append("     AND (CH0501.EVENT_CD, CH0501.EVENT_YMD) = ")
					.append("     (SELECT CH0501_MAX.EVENT_CD, MAX(CH0501_MAX.EVENT_YMD) AS CH0501_MAX ")
					.append("        FROM CH_M_PRC_SCHDL_TEIGI CH0501_MAX  ")
					.append("       WHERE CH0501_MAX.EVENT_CD = CH0501.EVENT_CD  ");
					
					if (templateID.equals(TEMPLATE_ID_EKK0361C040))
					{
						sql_Buff.append("         AND CH0501_MAX.EVENT_YMD < ? ");
					}
					else
					{
						sql_Buff.append("         AND CH0501_MAX.EVENT_YMD <= ? ");
					}
			
					sql_Buff.append("         AND CH0501_MAX.MK_FLG = '0' ")
					.append("     GROUP BY CH0501_MAX.EVENT_CD ")
					.append("      ) ");

			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 1, JKKModelCommon.getOpeDate(inCBSMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// 検索結果が0件の場合
			if (rsltQuery == null)
			{
				return null;
			}

			String seikyYm = null;

			// 請求年月を取得する
			if (rsltQuery.next())
			{
				seikyYm = rsltQuery.getString("SEIKY_YM");
			}
			
			// 請求年月を元に末日を付与して返却します
			return seikyYm.concat(JPCDateUtil.getEndOfMonth(seikyYm));
		}
		catch (SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch (SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
	}

	/**
	 * <p>
	 * 配送から配送完了年月日を取得します
	 * @param inETMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 配送年月日
	 * </p>
	 */
	private String getDK0011HaisoFinYmd(CAANMsg inETMsg, AgentDispatchContext inContext)
	{
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(DK0011ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("     DK0011.HAISO_FIN_YMD AS HAISO_FIN_YMD ")
					.append(" FROM ")
					.append("     (SELECT  ")
					.append("             KK0341.*  ")
					.append("            ,ROW_NUMBER() OVER (PARTITION BY KK0341.SVC_KEI_NO ORDER BY KK0341.SHOSA_YMD DESC) AS LINE  ")
					.append("      FROM   KK_T_KKTK_SVC_KEI KK0341   ")
					.append("      WHERE  KK0341.SVC_KEI_NO = ?  ")
					.append("        AND  KK0341.KKTK_SVC_KEI_STAT = '100'  ")
					.append("        AND  KK0341.TAKNKIKI_SBT_CD = 'P0'   ")
					.append("        AND  (KK0341.KKTK_SVC_KEI_NO, KK0341.RSV_APLY_YMD || KK0341.GENE_ADD_DTM) =   ")
					.append("             (SELECT KK0341_GENE.KKTK_SVC_KEI_NO, MAX(KK0341_GENE.RSV_APLY_YMD || KK0341_GENE.GENE_ADD_DTM) AS KK0341_MAX  ")
					.append("              FROM KK_T_KKTK_SVC_KEI KK0341_GENE  ")
					.append("              WHERE KK0341_GENE.KKTK_SVC_KEI_NO = KK0341.KKTK_SVC_KEI_NO  ")
					.append("                AND KK0341_GENE.RSV_APLY_CD = '2'  ")
					.append("                AND KK0341_GENE.RSV_APLY_YMD <= ?  ")
					.append("                AND KK0341_GENE.MK_FLG = '0'  ")
					.append("              GROUP BY KK0341_GENE.KKTK_SVC_KEI_NO ")
					.append("             )  ")
					.append("      ) KK0341_01  ")
					.append("     INNER JOIN DK_T_HAISO_TG_BPIN DK0021 ")
					.append("     ON KK0341_01.KKTK_SVC_KEI_NO = DK0021.KKTK_SVC_KEI_NO ")
					.append("     INNER JOIN DK_T_HAISO DK0011 ")
					.append("     ON DK0011.HAISO_NO = DK0021.HAISO_NO ")
					.append(" WHERE  ")
					.append("     DK0021.HAISO_TAIBPIN_NO =    ")
					.append("         (SELECT MAX(DK0021_GENE.HAISO_TAIBPIN_NO) AS DK0021_MAX   ")
					.append("            FROM DK_T_HAISO_TG_BPIN DK0021_GENE   ")
					.append("           WHERE DK0021_GENE.KKTK_SVC_KEI_NO = DK0021.KKTK_SVC_KEI_NO   ")
					.append("             AND DK0021_GENE.MK_FLG = '0'  ")
					.append("           GROUP BY DK0021_GENE.KKTK_SVC_KEI_NO  ")
					.append("         )  ")
					.append("     AND DK0011.HAISO_STAT = '004'  ")
					.append("     AND DK0011.HAISO_FIN_YMD IS NOT NULL  ")
					.append("     AND DK0011.MK_FLG = '0' ")
					// ++++++++++ v9.00.02 変更開始 ++++++++++ //
//					.append(" ORDER BY DK0011.HAISO_FIN_YMD DESC  ");
					.append(" ORDER BY DK0011.HAISO_FIN_YMD ASC  ");
					// ++++++++++ v9.00.02 変更終了 ++++++++++ //
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(サービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, inETMsg.getString(KK0081ETMsg.SVC_KEI_NO));
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inETMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			String haisoFinYmd = null;

			// 配送完了日を取得する
			if (rsltQuery.next())
			{
				haisoFinYmd = rsltQuery.getString("HAISO_FIN_YMD");
			} else {
				return null;
			}
			
			// 配送完了日に10日足して返却します
			return JPCDateUtil.addDay(haisoFinYmd, 10);
		}
		catch (SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch (SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
	}

	/**
	 * <p>
	 * オプションサービス契約の登録を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0351Msg　オプションサービス契約のETメッセージ
	 */
	private void createKK0351(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0351Msg)
	{
		JKKejbDBAUtil dbaU = new JKKejbDBAUtil(inCBSMsg);
		dbaU.create(kk0351Msg);
	}

	/**
	 * <p>
	 * 異動予約の登録を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk1681Msg　異動予約のETメッセージ
	 */
	private void createKK1681(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk1681Msg)
	{
		JKKejbDBAUtil dbaU = new JKKejbDBAUtil(inCBSMsg);
		dbaU.create(kk1681Msg);
	}

	/**
	 * <p>
	 * エラー返却項目にエラーフラグを設定します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param status エラー時のステータス
	 * @param errInfo[] エラー情報が設定された配列 [0]:エラーフラグ [1]:エラー返却項目
	 */
	private void setErrInfo(CAANMsg inCBSMsg, int status, String[] errInfo)
	{
		inCBSMsg.set(JCMConstants.STATUS_INT_KEY, status);
		inCBSMsg.set(errInfo[1], errInfo[0]);
		return;	
	}

	/**
	 * <p>
	 * 申込期間を取得する
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param mskmYmd 申込日
	 * @param svcStaYmd サービス開始日
	 * @param svcChrgStaymd サービス課金開始日
	 * @return 申込期間
	 */
	private String getMskmPeriod(CAANMsg inCBSMsg, String mskmYmd, String svcStaYmd, String svcChrgStaymd)
	{
		// 申込期間を取得
		JKKejbRule0088001 rule0088 = new JKKejbRule0088001(inCBSMsg);
		rule0088.setMskm_ymd(mskmYmd);
		rule0088.setSvc_sta_ymd(svcStaYmd);
		rule0088.setSvc_chrg_staymd(svcChrgStaymd);
		return rule0088.getMskmPeriodDef();
	}

	/**
	 * <p>
	 * 課金開始日設定の相関ルールを呼び出し課金開始年月日を取得します
	 * （更新契機が解約時のケース）
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param kk0351Msg オプションサービス契約のカレント検索結果
	 * @param kk0081Msg サービス契約のカレント検索結果
	 * @return 相関ルールより取得した課金開始年月日
	 */
	public String chrgStaYmdRuleRunForDsl(CAANMsg inMsg, CAANMsg kk0351Msg, CAANMsg kk0081Msg)
	{
		String staymd = null;        // サービス開始年月日(またはプラン開始年月日)(オプションカレント)
		String endymd = null;        // サービス終了年月日(またはプラン終了年月日)
		String chrgStaymd = null;    // サービス課金開始年月日(またはプラン課金開始年月日)(オプションカレント)
		String chrgEndymd = null;    // サービス課金終了年月日(またはプラン課金終了年月日)
		String dsljiChrgFlg = null;  // 解約時課金フラグ

		// サービスインターフェイスID
		String templateID = inMsg.getString(JCMConstants.TEMPLATE_ID_KEY);
		// 呼出元：オプションサービス契約解約確定
		if ("EKK0351C250".equals(templateID))
		{
			staymd = kk0351Msg.getString(KK0351ETMsg.SVC_STAYMD);
			endymd = inMsg.getString(EKK0351C250CBSMsg.SVC_ENDYMD);
			chrgStaymd = kk0351Msg.getString(KK0351ETMsg.SVC_CHRG_STAYMD);
			chrgEndymd = inMsg.getString(EKK0351C250CBSMsg.SVC_CHRG_ENDYMD);
			dsljiChrgFlg = inMsg.getString(EKK0351C250CBSMsg.DSLJI_CHRG_FLG);
			// OM-2014-0003837 ADD START
			// 解約時課金フラグが課金の場合
			if (DSLJI_CHRG_FLG_CHRG.equals(dsljiChrgFlg) && !kk0081Msg.isNull(KK0081ETMsg.SVC_CHRG_STAYMD) && null != chrgEndymd)
			{
				// 検索結果のオプションサービス契約ステータスが締結済以外の場合かつネットの場合
				// (受付済及び照査済からはオプションサービス契約解約確定・プラン変からは呼ばれない。
				//  締結済の場合はサービス課金開始日が未設定である。）
				if (!JKKModelConst.SVC_KEI_STAT_CNC_ZM.equals(kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_STAT)) &&
						JKKModelConst.SVC_CD_NET.equals(kk0081Msg.getString(KK0081ETMsg.SVC_CD)))
				{
					// 親サービス契約のサービス課金開始年月日 ≦ サービス課金終了年月日でない場合
					if (!JKKModelCommon.isPastDate(kk0081Msg.getString(KK0081ETMsg.SVC_CHRG_STAYMD), chrgEndymd, "1"))
					{
						// 解約時課金フラグは非課金とする
						dsljiChrgFlg = DSLJI_CHRG_FLG_NO_CHRG;
					}
				}
			}
			// OM-2014-0003837 ADD END
		}
		// 呼出元：オプションサービス契約料金プラン変更確定
		else if ("EKK0351C130".equals(templateID))
		{
			staymd = kk0351Msg.getString(KK0351ETMsg.PLAN_STAYMD);
			endymd = inMsg.getString(EKK0351C130CBSMsg.PLAN_ENDYMD);
			chrgStaymd = kk0351Msg.getString(KK0351ETMsg.PLAN_CHRG_STAYMD);
			chrgEndymd = inMsg.getString(EKK0351C130CBSMsg.PLAN_CHRG_ENDYMD);
			dsljiChrgFlg = inMsg.getString(EKK0351C130CBSMsg.DSLJI_CHRG_FLG);
		}

		// 相関ルールを呼び出す為にインスタンス生成する
		JKKejbRule0066001 instance = new JKKejbRule0066001(inMsg);

		// 課金開始前／開始後を判定する
		String dslStaZengo = null;

		// 検索結果のオプションサービス契約ステータスが締結済以外の場合
		// (受付済及び照査済からはオプションサービス契約解約確定・プラン変からは呼ばれない。
		//  締結済の場合はサービス課金開始日が未設定である。）
		if (!JKKModelConst.SVC_KEI_STAT_CNC_ZM.equals(kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_STAT))
			&& null != chrgStaymd && null != chrgEndymd)
		{
			// サービス課金開始年月日(またはプラン課金開始年月日) ≦ サービス課金終了年月日(またはプラン課金終了年月日) の場合
			if (JKKModelCommon.isPastDate(chrgStaymd, chrgEndymd, "1"))
			{
				// 課金開始後解約
				dslStaZengo = "1";
			}
			// サービス課金開始年月日(またはプラン課金開始年月日) ＞ サービス課金終了年月日(またはプラン課金終了年月日) の場合
			else
			{
				// 課金開始前解約
				dslStaZengo = "0";
			}
		}
		else
		{
			// 課金開始前解約
			dslStaZengo = "0";
		}

		instance.setSvc_cd(kk0081Msg.getString(KK0081ETMsg.SVC_CD));        // サービスコード
		instance.setUpd_type("0");                                          // 更新契機(解約時)
		instance.setOp_svc_cd(kk0351Msg.getString(KK0351ETMsg.OP_SVC_CD));  // オプションサービスコード
		instance.setDslji_chrg(dsljiChrgFlg);      // 解約時課金フラグ
		instance.setDsl_sta_zengo(dslStaZengo);    // 課金開始前／開始後
		instance.setSvc_sta_ymd(staymd);           // サービス開始年月日(またはプラン開始年月日)(オプションカレント)
		instance.setSvc_chrg_sta_ymd(chrgStaymd);  // サービス課金開始年月日(またはプラン課金開始年月日)(オプションカレント)
		instance.setSvc_end_ymd(endymd);           // サービス終了年月日(またはプラン終了年月日)
// ▽▽▽ ANK-3484-00-00 ADD START
		instance.setBefor_svc_chrg_end_ymd(null);  // 引継は存在しない
// △△△ ANK-3484-00-00 ADD END
		// 相関ルールを実行して結果を返却する
		return instance.getChrgStaYmd();
	}
	
	/**
	 * <p>
	 * サービス契約番号に紐づくオプションサービス契約を遡及解約します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcChrgEndYmd サービス課金終了年月日
	 */
	public void sokyuKK0351(CAANMsg inCBSMsg, String svcChrgEndYmd)
	{
		CAANMsg[] kk0351List;
		String opedate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		JKKejbKK0351DBABase dbaBase = new JKKejbKK0351DBABase();
		
		// サービス契約番号に紐づくオプションサービス契約を取得
		kk0351List = dbaBase.getKK0351bySvcKei(inCBSMsg.getString(EKK0081C260CBSMsg.SVC_KEI_NO), null, opedate, "3");
		
		for (CAANMsg kk0351Data : kk0351List)
		{
			// オプションサービス契約ステータスが解約済でサービス契約よりも課金終了年月日が遅い場合
			if (JKKModelConst.SVC_KEI_STAT_DSL_ZM.equals(kk0351Data.getString(KK0351ETMsg.OP_SVC_KEI_STAT))
					&& !kk0351Data.isNull(KK0351ETMsg.SVC_CHRG_ENDYMD)
					&& kk0351Data.getString(KK0351ETMsg.SVC_CHRG_ENDYMD).compareTo(svcChrgEndYmd) > 0
					&& (inCBSMsg.isNull(EKK0081C260CBSMsg.MSKM_DTL_NO) 
							|| !inCBSMsg.getString(EKK0081C260CBSMsg.MSKM_DTL_NO).equals(kk0351Data.getString(KK0351ETMsg.MSKM_DTL_NO))))
			{
				String svcEndYmd = inCBSMsg.getString(EKK0081C260CBSMsg.SVC_ENDYMD);
				
				// 遡及解約に伴う更新処理
				CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());
				inETMsg.set(KK0351ETMsg.OP_SVC_KEI_NO, kk0351Data.getString(KK0351ETMsg.OP_SVC_KEI_NO)); // オプションサービス契約番号
				inETMsg.set(KK0351ETMsg.GENE_ADD_DTM, kk0351Data.getString(KK0351ETMsg.GENE_ADD_DTM)); // 世代登録年月日時分秒
				inETMsg.set(KK0351ETMsg.OP_SVC_KEI_STAT, JKKModelConst.SVC_KEI_STAT_DSL_ZM); // オプションサービス契約ステータス
				inETMsg.set(KK0351ETMsg.PLAN_ENDYMD, svcEndYmd); // プラン終了年月日
				inETMsg.set(KK0351ETMsg.PLAN_CHRG_ENDYMD, svcChrgEndYmd); // プラン課金終了年月日
				
				// 予約適用年月日
				if (opedate.compareTo(svcEndYmd) > 0)
				{
					// サービス終了年月日が運用日付より過去の場合運用日付を設定
					inETMsg.set(KK0351ETMsg.RSV_APLY_YMD, opedate);
				}
				else
				{
					// 上記以外の場合サービス終了年月日を設定
					inETMsg.set(KK0351ETMsg.RSV_APLY_YMD, svcEndYmd);
				}
				
				inETMsg.set(KK0351ETMsg.RSV_APLY_CD, JKKModelConst.RSV_APLY_CD_RSV_FIX); // 予約適用コード
				inETMsg.set(KK0351ETMsg.SVC_ENDYMD, svcEndYmd); // サービス終了年月日
				inETMsg.set(KK0351ETMsg.SVC_CHRG_ENDYMD, svcChrgEndYmd); // サービス課金終了年月日
				inETMsg.set(KK0351ETMsg.SVC_DLRE_CD, inCBSMsg.getString(EKK0081C260CBSMsg.SVC_DLRE_CD)); // サービス解約理由コード
				inETMsg.set(KK0351ETMsg.SVC_DLRE_MEMO, inCBSMsg.getString(EKK0081C260CBSMsg.SVC_DLRE_MEMO)); // サービス解約理由メモ
				inETMsg.set(KK0351ETMsg.UPD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
				inETMsg.set(KK0351ETMsg.UPD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
				
				JKKejbDBAUtil dbaUtil = new JKKejbDBAUtil(inCBSMsg);
				dbaUtil.update(inETMsg);
			}
			
			// サブオプションサービス契約の遡及解約
			new JKKejbKK0401ETDA().sokyuKK0401(inCBSMsg, kk0351Data.getString(KK0351ETMsg.OP_SVC_KEI_NO), svcChrgEndYmd);
		}
	}
// ▽▽▽ ANK-3484-00-00 ADD START
	
	/**
	 * <p>
	 * オプションサービス契約<ISP>のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約のカレントレコード
	 */
	private CAANMsg getCurOpKeiIsp(CAANMsg inCBSMsg, AgentDispatchContext inContext, String opSvcKeiNo)
	{
		
		CAANMsg kk0361Cond = new CAANMsg(KK0361ETMsg.class.getName());
		kk0361Cond.set(KK0361ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		
		return new JKKejbKK0361DBABase().findByCurrent(kk0361Cond);
	}
	/**
	 * 解約済の端末補償の引継元課金終了日を取得する。(複数存在する場合は、直近の日付）
	 * <p>
	 * @param inETMsg   メッセージ
	 * @param inContext コンテキスト
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param opSvcCd オプションサービスコード
	 */
	public String getTmcpPreviousSvcChrgEnd(CAANMsg inETMsg, AgentDispatchContext inContext, String opSvcKeiNo, String opSvcCd)
	{
		// 端末補償以外のオプションの場合、検索を行わない
		if (!TMCP_OP_SVC_CD_LIST.contains(opSvcCd))
		{
			return null;
		}
		
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0351ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("     MAX(KK0351.SVC_CHRG_ENDYMD) AS SVC_CHRG_ENDYMD ")
					.append(" FROM KK_T_OP_SVC_KEI KK0351")
					.append(" WHERE ")
					.append("     KK0351.OP_SVC_KEI_NO IN")
					.append("      (")
					.append("         SELECT KK0361.OP_SVC_KEI_NO")
					.append("           FROM KK_T_OPSVKEI_ISP KK0361")
					.append("           WHERE ")
					.append("               KK0361.OP_SVC_KEI_NO != ?")
					.append("             AND ")
					.append("               KK0361.TMCP_KEI_NO IN (")
					.append("                 SELECT KK0361_TMCP.TMCP_KEI_NO  ")
					.append("                   FROM KK_T_OPSVKEI_ISP KK0361_TMCP ")
					.append("                   WHERE KK0361_TMCP.OP_SVC_KEI_NO = ?")
					.append("               ) ")
					.append("             AND ")
					.append("               KK0361.MK_FLG = '0'")
					.append("      )")
					.append("   AND")
					.append("     (KK0351.RSV_APLY_YMD || KK0351.GENE_ADD_DTM) =")
					.append("      (")
					.append("         SELECT MAX(KK0351_MAX.RSV_APLY_YMD || KK0351_MAX.GENE_ADD_DTM)")
					.append("            FROM KK_T_OP_SVC_KEI KK0351_MAX")
					.append("             WHERE ")
					.append("                 KK0351_MAX.OP_SVC_KEI_NO = KK0351.OP_SVC_KEI_NO")
					.append("               AND")
					.append("                 KK0351_MAX.RSV_APLY_YMD <= ?")
					.append("               AND")
					.append("                 KK0351_MAX.RSV_APLY_CD = '2'")
					.append("               AND ")
					.append("                 KK0351_MAX.MK_FLG = '0'")
					.append("       )")
					.append("   AND")
					.append("     KK0351.OP_SVC_KEI_STAT = '910'")
					.append("   AND")
					.append("     KK0351.MK_FLG = '0'");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(オプションサービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, opSvcKeiNo);
			// パラメータの設定(オプションサービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, 2, opSvcKeiNo);
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inETMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			String chagEndYmd = "";

			// 課金終了日を取得する
			if (rsltQuery.next())
			{
				chagEndYmd = rsltQuery.getString("SVC_CHRG_ENDYMD");
			}
			
			return chagEndYmd;
		}
		catch (SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch (SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
	}
// ▲▲▲ ANK-3484-00-00 ADD END 
// ▽▽▽ ANK-3754-00-00 ADD STRAT
	/**
	 * <p>
	 * 多機能ルータの出荷日、配送方法コード、工事完了日
	 * @param inETMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 出荷日
	 * @return 配送先工事会社コード
	 * @return 工事完了日
	 * </p>
	 */
	private HashMap<String, Object> getTknuinfo(CAANMsg inETMsg, AgentDispatchContext inContext, CAANMsg kk0081Cur)
	{
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(DK0011ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("  DK0011.HAISO_FIN_YMD, ")
					.append("  DK0011.HISOS_KOCOMP_CD, ")
// ▽▽▽ IT2-2020-0000014 ADD START
					.append("  DK0021.KOJIAK_NO, ")
// △△△ IT2-2020-0000014 ADD END
					.append("  KU0011.KOJIAK_JSSI_YMD ")
					.append(" FROM ")
					.append("  KK_T_KAISEN_TG_SVKEI KK0241 ")
					.append(" INNER JOIN ")
					.append("  KK_T_KKTK_SVC_KEI KK0341 ")
					.append(" ON ")
					.append("  KK0241.SVC_KEI_KAISEN_UCWK_NO = KK0341.SVC_KEI_KAISEN_UCWK_NO ")
					.append(" AND ")
// ▽▽▽ ANK-4315-00-00 MOD START
					//.append("  KK0341.TAKNKIKI_SBT_CD = 'R0'")
					.append("  KK0341.TAKNKIKI_SBT_CD IN ('R0' , 'S0') ")
// △△△ ANK-4315-00-00 MOD END
					.append(" INNER JOIN ")
					.append("  DK_T_HAISO_TG_BPIN DK0021 ")
					.append(" ON ")
					.append("  DK0021.KIKI_CHG_NO = KK0341.KIKI_CHG_NO ")
					.append(" INNER JOIN ")
					.append("  DK_T_HAISO DK0011 ")
					.append(" ON ")
					.append("  DK0011.HAISO_NO = DK0021.HAISO_NO ")
					.append(" LEFT OUTER JOIN ")
					.append("  KU_T_KOJIAK KU0011 ")
					.append(" ON ")
					.append("  KU0011.KOJIAK_NO = DK0021.KOJIAK_NO ")
					.append(" WHERE ")
					.append("  KK0241.SVC_KEI_NO = ? ")
					.append(" AND KK0241.KAISEN_UCWK_USE_STAYMD <= ? ")
					.append(" AND KK0241.KAISEN_UCWK_USE_ENDYMD >= ? ")
					.append(" AND KK0241.MK_FLG = '0' ")
					.append(" AND ")
					.append("  DK0011.HAISO_STAT = '004' ")
					.append(" AND ")
					.append("  DK0011.HAISO_FIN_YMD IS NOT NULL ")
					.append(" AND ")
					.append("  KK0341.RSV_APLY_YMD || KK0341.GENE_ADD_DTM = ( ")
					.append("   SELECT MAX(KK0341_GENE_01.RSV_APLY_YMD || KK0341_GENE_01.GENE_ADD_DTM) AS KK0341_MAX  ")
					.append("          FROM   KK_T_KKTK_SVC_KEI KK0341_GENE_01  ")
					.append("          WHERE  KK0341_GENE_01.KKTK_SVC_KEI_NO = KK0341.KKTK_SVC_KEI_NO  ")
					.append("          AND    KK0341_GENE_01.RSV_APLY_CD = '2'  ")
					.append("          AND    KK0341_GENE_01.RSV_APLY_YMD <= ?  ")
					.append("          AND    KK0341_GENE_01.MK_FLG = '0' ) ")
					.append(" AND ")
					.append("  KK0341.KKTK_SVC_KEI_STAT NOT IN ('910','920') ");
// ▽▽▽ #84334 ADD START
			sql_Buff.append(" ORDER BY KK0341.KKTK_SVC_KEI_STAT DESC ");
// △△△ #84334 ADD END
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(サービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, kk0081Cur.getString(KK0081ETMsg.SVC_KEI_NO));
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inETMsg));
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inETMsg));
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 4, JKKModelCommon.getOpeDate(inETMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			String haisoFinYmd = null;
			String hisos_kocomp_cd = null;
			String kojiakFinYmd = null;

			// 配送完了日、配送先工事会社コード、工事完了日を取得する
			if (rsltQuery.next())
			{
				haisoFinYmd = rsltQuery.getString("HAISO_FIN_YMD");
// ▽▽▽ IT2-2020-0000014 ADD START
//				hisos_kocomp_cd = rsltQuery.getString("HISOS_KOCOMP_CD");
				// 配送先工事会社コードに設定されない場合があるため、工事案件番号で代用する
				hisos_kocomp_cd = rsltQuery.getString("KOJIAK_NO");
// △△△ IT2-2020-0000014 ADD END
				kojiakFinYmd = rsltQuery.getString("KOJIAK_JSSI_YMD");
			} else {
				return null;
			}
			
			// 配送完了日に10日足して返却します
			if(null != haisoFinYmd)
			{
				haisoFinYmd = JPCDateUtil.addDay(haisoFinYmd, 10);
			}
			
			HashMap<String, Object> haisoinfo = new HashMap<String, Object>();
			
			haisoinfo.put("HAISO_FIN_YMD", haisoFinYmd);
			haisoinfo.put("HISOS_KOCOMP_CD", hisos_kocomp_cd);
			haisoinfo.put("KOJIAK_JSSI_YMD", kojiakFinYmd);
			
			return haisoinfo;
		}
		catch (SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch (SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
	}
// △△△ ANK-3754-00-00 ADD END

}
