/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbRule0065001
*	ソースファイル名：JKKejbRule0065001.java
*	作成者			：富士通
*	日付			：2011年11月10日
*＜機能概要＞
*	課金開始日設定(サービス)相関ルール部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/11/10	FJ)			新規作成
*	v5.00.00	2013/07/20	FJ)寺園	 	LT-2013-0000544
*	v6.00.00	2013/12/15	FJ)大山	 	OM-2013-0004533
*   v8.00.00    2014/06/04  FJ) 団      OM-2014-0001332
*   v74.00.00	2024/12/26	FJ)森下	 	【ANK-4592-00-00】テレビ新コース（スカパー用）導入対応）
*
**********************************************************************/

package eo.ejb.common.rule;

import java.sql.SQLException;
import java.text.ParseException;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbDBAccess;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;

import eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0251ETMsg;
import eo.ejb.cbm.entity.KK0341ETMsg;
import eo.ejb.cbm.entity.KK0341LE;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0251DBABase;
import eo.ejb.common.db.JKKejbKK0341DBABase;

/**
 * <p>
 * 課金開始日設定(サービス)相関ルール部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbRule0065001 extends JKKejbRuleBase
{

	/** ルールID */
	private static final String RULE_ID = "RULE0065001";

	/** 異動区分 */
	private static final String IDO_DIV = "IDO_DIV";

	/** サービスコード */
	private static final String SVC_CD = "SVC_CD";

	/** 回線提供会社コード */
	private static final String KAISEN_TK_COMP_CD = "KAISEN_TK_COMP_CD";

	/** 料金グループコード */
	private static final String PRC_GRP_CD = "PRC_GRP_CD";

	/** 工事有無 */
	private static final String KOJI_UM = "KOJI_UM";

	/** 課金開始日補正有無 */
	private static final String CHRG_STA_YMD_HOSEI_UM = "CHRG_STA_YMD_HOSEI_UM";

	/** 機器提供種別コード */
	private static final String KKTK_SBT_CD = "KKTK_SBT_CD";

	/** インターネットサービス同時申込有無 */
	private static final String INSVC_DOJI_MSKM_UM = "INSVC_DOJI_MSKM_UM";

	/** 住所変更異動詳細コード */
	private static final String ADCHG_IDO_DTL_CD = "ADCHG_IDO_DTL_CD";

	/** 機器出荷有無 */
	private static final String KKSHKA_UM = "KKSHKA_UM";

	// ANK-4592-00-00 ADD START
	/** 即時適用有無 */
	private static final String SOKUJI_APLY_UM = "SOKUJI_APLY_UM";
	// ANK-4592-00-00 ADD END

	/** 基準日 */
	private static final String STD_DT = "STD_DT";

	/** 基準日からの相対日 */
	private static final String RELATIVE_DATE_COUNT = "RELATIVE_DATE_COUNT";

	/** 優先基準日 */
	private static final String PRIORITY_STD_DT = "PRIORITY_STD_DT";

	/** 基準日(サービス開始日) */
	private static final String STD_DT_KK0081_SVC_STA = "1";

	/** 基準日(プラン開始日) */
	private static final String STD_DT_KK0081_PLAN_STA = "2";
	
	/** 基準日(機器提供サービス契約プラン開始年月日) */
	private static final String STD_DT_KK0341_PLAN_STA = "3";

	/** 基準日からの相対日(翌月月初) */
	private static final String RELATIVE_DATE_COUNT_NEXT = "";

	/** 優先基準日(eo光ネット・課金開始日と大きい方) */
	private static final String PRIORITY_STD_DT_NET = "1";

	/** 優先基準日(入力．課金開始日) */
	private static final String PRIORITY_STD_DT_CHRG_STAYMD = "2";

	/** 月初設定用 */
	private static final String GESYO_SETTEI = "01";
	
	/** 機器提供サービスコード(STB) */
	private static final String KKTK_SVC_CD_STB = "C009";
	
	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** 異動区分 */
	private String ido_div = null;

	/** サービスコード */
	private String svc_cd = null;

	/** 回線提供会社コード */
	private String kaisen_tk_comp_cd = null;

	/** 料金グループコード */
	private String prc_grp_cd = null;

	/** 工事有無 */
	private String koji_um = null;

	/** 課金開始日補正有無 */
	private String chrg_sta_ymd_hosei_um = null;

	/** 機器提供種別コード */
	private String kktk_sbt_cd = null;

	/** インターネットサービス同時申込有無 */
	private String insvc_doji_mskm_um = null;

	/** 住所変更異動詳細コード */
	private String adchg_ido_dtl_cd = null;

	/** 申込明細番号 */
	private String mskm_dtl_no = null;

	/** サービス開始年月日 */
	private String svc_sta_ymd = null;

	/** プラン開始年月日 */
	private String plan_staymd = null;

	/** プラン課金開始年月日 */
	private String plan_chrg_staymd = null;

	/** サービス契約内訳番号 */
	private String svc_kei_ucwk_no = null;

	/** 機器出荷有無 */
	private String kkshka_um = null;

	// ANK-4592-00-00 ADD START
	/** 即時適用有無 */
	private String sokuji_aply_um = null;
	// ANK-4592-00-00 ADD END

	/**
	 * <p>
	 * JKKejbRule0065001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0065001(CAANMsg inMsg)
	{
		super();
		this.inCBSMsg = inMsg;
	}

	/**
	 * <p>
	 * 処理対象のCBSMsgを取得します。
	 * </p>
	 * @return 処理対象のCBSMsg
	 */
	protected CAANMsg getCBSMsg()
	{
		return this.inCBSMsg;
	}

	/**
	 * <p>
	 * ルールIDを取得します。
	 * </p>
	 * @return ルールID
	 */
	protected String getRuleId()
	{
		return RULE_ID;
	}

	/**
	 * <p>
	 * ルールエンジンを複数条件モードで実行するか設定します。
	 * </p>
	 * @return 複数条件モードで実行する場合はtrue
	 */
	protected boolean isMultiMode()
	{
		return true;
	}

	/**
	 * <p>
	 * 異動区分を取得します。
	 * </p>
	 * @return 異動区分
	 */
	private String getIdo_div()
	{
		return this.ido_div;
	}

	/**
	 * <p>
	 * サービスコードを取得します。
	 * </p>
	 * @return サービスコード
	 */
	private String getSvc_cd()
	{
		return this.svc_cd;
	}

	/**
	 * <p>
	 * 回線提供会社コードを取得します。
	 * </p>
	 * @return 回線提供会社コード
	 */
	private String getKaisen_tk_comp_cd()
	{
		return this.kaisen_tk_comp_cd;
	}

	/**
	 * <p>
	 * 料金グループコードを取得します。
	 * </p>
	 * @return 料金グループコード
	 */
	private String getPrc_grp_cd()
	{
		return this.prc_grp_cd;
	}

	/**
	 * <p>
	 * 工事有無を取得します。
	 * </p>
	 * @return 工事有無
	 */
	private String getKoji_um()
	{
		return this.koji_um;
	}

	/**
	 * <p>
	 * 課金開始日補正有無を取得します。
	 * </p>
	 * @return 課金開始日補正有無
	 */
	private String getChrg_sta_ymd_hosei_um()
	{
		return this.chrg_sta_ymd_hosei_um;
	}

	/**
	 * <p>
	 * 機器提供種別コードを取得します。
	 * </p>
	 * @return 機器提供種別コード
	 */
	private String getKktk_sbt_cd()
	{
		return this.kktk_sbt_cd;
	}

	/**
	 * <p>
	 * インターネットサービス同時申込有無を取得します。
	 * </p>
	 * @return インターネットサービス同時申込有無
	 */
	private String getInsvc_doji_mskm_um()
	{
		return this.insvc_doji_mskm_um;
	}

	/**
	 * <p>
	 * 住所変更異動詳細コードを取得します。
	 * </p>
	 * @return 住所変更異動詳細コード
	 */
	private String getAdchg_ido_dtl_cd()
	{
		return this.adchg_ido_dtl_cd;
	}

	/**
	 * <p>
	 * 申込明細番号を取得します。
	 * </p>
	 * @return 申込明細番号
	 */
	private String getMskm_dtl_no()
	{
		return this.mskm_dtl_no;
	}

	/**
	 * <p>
	 * サービス開始年月日を取得します。
	 * </p>
	 * @return サービス開始年月日
	 */
	private String getSvc_sta_ymd()
	{
		return this.svc_sta_ymd;
	}

	/**
	 * <p>
	 * プラン開始年月日を取得します。
	 * </p>
	 * @return プラン開始年月日
	 */
	private String getPlan_staymd()
	{
		return this.plan_staymd;
	}
	
	/**
	 * <p>
	 * 機器出荷有無を取得します。
	 * </p>
	 * @return 機器出荷有無
	 */
	private String getKkshka_um()
	{
		return this.kkshka_um;
	}

	// ANK-4592-00-00 ADD START
	/**
	 * <p>
	 * 即時適用有無を取得します。
	 * </p>
	 * @return 即時適用有無
	 */
	private String getSokuji_aply_um()
	{
		return this.sokuji_aply_um;
	}
	// ANK-4592-00-00 ADD END

	/**
	 * <p>
	 * 異動区分を設定します。
	 * </p>
	 * @param p_ido_div 異動区分
	 */
	public void setIdo_div(String p_ido_div)
	{
		this.ido_div = p_ido_div;
	}

	/**
	 * <p>
	 * サービスコードを設定します。
	 * </p>
	 * @param p_svc_cd サービスコード
	 */
	public void setSvc_cd(String p_svc_cd)
	{
		this.svc_cd = p_svc_cd;
	}

	/**
	 * <p>
	 * 回線提供会社コードを設定します。
	 * </p>
	 * @param p_kaisen_tk_comp_cd 回線提供会社コード
	 */
	public void setKaisen_tk_comp_cd(String p_kaisen_tk_comp_cd)
	{
		this.kaisen_tk_comp_cd = p_kaisen_tk_comp_cd;
	}

	/**
	 * <p>
	 * 料金グループコードを設定します。
	 * </p>
	 * @param p_prc_grp_cd 料金グループコード
	 */
	public void setPrc_grp_cd(String p_prc_grp_cd)
	{
		this.prc_grp_cd = p_prc_grp_cd;
	}

	/**
	 * <p>
	 * 工事有無を設定します。
	 * </p>
	 * @param p_koji_um 工事有無
	 */
	public void setKoji_um(String p_koji_um)
	{
		this.koji_um = p_koji_um;
	}

	/**
	 * <p>
	 * 課金開始日補正有無を設定します。
	 * </p>
	 * @param p_chrg_sta_ymd_hosei_um 課金開始日補正有無
	 */
	public void setChrg_sta_ymd_hosei_um(String p_chrg_sta_ymd_hosei_um)
	{
		this.chrg_sta_ymd_hosei_um = p_chrg_sta_ymd_hosei_um;
	}

	/**
	 * <p>
	 * 機器提供種別コードを設定します。
	 * </p>
	 * @param p_kktk_sbt_cd 機器提供種別コード
	 */
	public void setKktk_sbt_cd(String p_kktk_sbt_cd)
	{
		this.kktk_sbt_cd = p_kktk_sbt_cd;
	}

	/**
	 * <p>
	 * インターネットサービス同時申込有無を設定します。
	 * </p>
	 * @param p_insvc_doji_mskm_um インターネットサービス同時申込有無
	 */
	public void setInsvc_doji_mskm_um(String p_insvc_doji_mskm_um)
	{
		this.insvc_doji_mskm_um = p_insvc_doji_mskm_um;
	}

	/**
	 * <p>
	 * 住所変更異動詳細コードを設定します。
	 * </p>
	 * @param p_adchg_ido_dtl_cd 住所変更異動詳細コード
	 */
	public void setAdchg_ido_dtl_cd(String p_adchg_ido_dtl_cd)
	{
		this.adchg_ido_dtl_cd = p_adchg_ido_dtl_cd;
	}

	/**
	 * <p>
	 * 申込明細番号を設定します。
	 * </p>
	 * @param p_mskm_dtl_no 申込明細番号
	 */
	public void setMskm_dtl_no(String p_mskm_dtl_no)
	{
		this.mskm_dtl_no = p_mskm_dtl_no;
	}

	/**
	 * <p>
	 * サービス開始年月日を設定します。
	 * </p>
	 * @param p_svc_sta_ymd サービス開始年月日
	 */
	public void setSvc_sta_ymd(String p_svc_sta_ymd)
	{
		this.svc_sta_ymd = p_svc_sta_ymd;
	}

	/**
	 * <p>
	 * プラン開始年月日を設定します。
	 * </p>
	 * @param p_plan_staymd プラン開始年月日
	 */
	public void setPlan_staymd(String p_plan_staymd)
	{
		this.plan_staymd = p_plan_staymd;
	}

	/**
	 * <p>
	 * プラン課金開始年月日を設定します。
	 * </p>
	 * @param p_plan_chrg_staymd プラン課金開始年月日
	 */
	public void setPlan_chrg_staymd(String p_plan_chrg_staymd)
	{
		this.plan_chrg_staymd = p_plan_chrg_staymd;
	}

	/**
	 * <p>
	 * サービス契約内訳番号を設定します。
	 * </p>
	 * @param p_svc_kei_ucwk_no サービス契約内訳番号
	 */
	public void setSvc_kei_ucwk_no(String p_svc_kei_ucwk_no)
	{
		this.svc_kei_ucwk_no = p_svc_kei_ucwk_no;
	}

	/**
	 * <p>
	 * 機器出荷有無を設定します。
	 * </p>
	 * @param p_kkshka_um 機器出荷有無
	 */
	public void setKkshka_um(String p_kkshka_um)
	{
		this.kkshka_um = p_kkshka_um;
	}

	/**
	 * <p>
	 * サービス契約内訳番号を取得します。
	 * </p>
	 * @return サービス契約内訳番号
	 */
	private String getSvc_kei_ucwk_no()
	{
		return this.svc_kei_ucwk_no;
	}

	// ANK-4592-00-00 ADD START
	/**
	 * <p>
	 * 即時適用有無を設定します。
	 * </p>
	 * @param p_sokuji_aply_um 即時適用有無
	 */
	public void setSokuji_aply_um(String p_sokuji_aply_um)
	{
		this.sokuji_aply_um = p_sokuji_aply_um;
	}
	// ANK-4592-00-00 ADD END
	
	/**
	 * <p>
	 * 課金開始日設定(サービス)の相関ルールにより課金開始日を算出する。
	 * </p>
	 * @return 相関ルールの結果により取得した課金開始年月日
	 */
	public String getChrgStaYmd()
	{
		// ログ出力
		execLogOutput();

		// ルールエンジンで使用する値を設定
		set(IDO_DIV, getIdo_div());
		set(SVC_CD, getSvc_cd());
		set(KAISEN_TK_COMP_CD, getKaisen_tk_comp_cd());
		set(PRC_GRP_CD, getPrc_grp_cd());
		set(KOJI_UM, getKoji_um());
		set(CHRG_STA_YMD_HOSEI_UM, getChrg_sta_ymd_hosei_um());
		set(KKTK_SBT_CD, getKktk_sbt_cd());
		set(INSVC_DOJI_MSKM_UM, getInsvc_doji_mskm_um());
		set(ADCHG_IDO_DTL_CD, getAdchg_ido_dtl_cd());
		set(KKSHKA_UM, getKkshka_um());
		// ANK-4592-00-00 ADD START
		set(SOKUJI_APLY_UM, getSokuji_aply_um());
		// ANK-4592-00-00 ADD END

		// ルールエンジンの実行
		super.execRuleEngine();

		// 実行結果が存在しない場合、nullを返す。
		if (!hasNext())
		{
			return null;
		}

		// ルールエンジン実行結果を取得
		HashMap<String, Object> retMap = getResultMap();


		// 基準日を取得
		String sStdDate = getStdDate(retMap);

		// 基準日が取得できなかった場合、nullを返す。
		if (null == sStdDate)
		{
			return null;
		}


		// 課金開始日を取得
		String sChrgStaYmd = getChrgStaYmd(retMap, sStdDate);

		// 優先基準日が"eo光ネット・課金開始日と大きい方"の場合
		if (PRIORITY_STD_DT_NET.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// メンバ変数に設定された申込明細番号を基に、
			// サービス契約のサービス課金開始年月日を取得する。
			String sSvcChrgStaymd = getSvcChrgStaymd();

			// サービス課金開始年月日が取得できた場合
			if (null != sSvcChrgStaymd)
			{
				// 課金開始日の値がサービス課金開始年月日より小さい場合
				if (0 > sChrgStaYmd.compareTo(sSvcChrgStaymd))
				{
					// 課金開始日にサービス課金開始年月日の値を設定
					sChrgStaYmd = sSvcChrgStaymd;
				}
			}
		}
		// 優先基準日が"入力．課金開始日"の場合
		if (PRIORITY_STD_DT_CHRG_STAYMD.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// プラン課金開始年月日が設定されている場合
			if (null != plan_chrg_staymd && !"".equals(plan_chrg_staymd))
			{
				sChrgStaYmd = plan_chrg_staymd;
			}
		}

		return sChrgStaYmd;
	}

	/**
	 * <p>
	 * 課金開始日を算出した値を返す。
	 * </p>
	 * @param retMap 相関ルール実行結果を格納したマップ
	 * @param sStdDate 基準日
	 * @return 相関ルールの実行結果の基準日からの相対日が「翌月月初」の場合
	 *          基準日から翌月1日を算出した値を課金開始日として返す。
	 *          相関ルールの実行結果の基準日からの相対日が「翌月月初」でない場合
	 *          基準日に基準日からの相対日を加算した値を課金開始日として返す。
	 */
	private String getChrgStaYmd(HashMap<String, Object> retMap, String sStdDate)
	{
		String sChrgStaYmd = null;

		// 基準日からの相対日を取得
		String sRelativeDateCount = (String)retMap.get(RELATIVE_DATE_COUNT);

		// 基準日からの相対日が"翌月月初"の場合
		if (null == sRelativeDateCount || RELATIVE_DATE_COUNT_NEXT.equals(sRelativeDateCount))
		{
			// 基準日から翌月1日を算出し、課金開始日とする。
			sChrgStaYmd = getBeginMonth(sStdDate);
		}
		else
		{
			// 基準日に「基準日からの相対日」を加算し、課金開始日とする。
			sChrgStaYmd = JKKModelCommon.addDay(sStdDate, Integer.parseInt(sRelativeDateCount));
		}
		
		return sChrgStaYmd;
	}

	/**
	 * <p>
	 * メンバ変数のログ出力を行う。
	 * </p>
	 */
	private void execLogOutput()
	{
		// 異動区分
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.ido_div=" + getIdo_div());

		// サービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.svc_cd=" + getSvc_cd());

		// 回線提供会社コード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.kaisen_tk_comp_cd=" + getKaisen_tk_comp_cd());

		// 料金グループコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.prc_grp_cd=" + getPrc_grp_cd());

		// 工事有無
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.koji_um=" + getKoji_um());

		// 課金開始日補正有無
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.chrg_sta_ymd_hosei_um=" + getChrg_sta_ymd_hosei_um());

		// 機器提供種別コード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.kktk_sbt_cd=" + getKktk_sbt_cd());

		// インターネットサービス同時申込有無
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.insvc_doji_mskm_um=" + getInsvc_doji_mskm_um());

		// 申込明細番号
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.mskm_dtl_no=" + getMskm_dtl_no());

		// ANK-4592-00-00 ADD START
		// 即時適用有無
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.sokuji_aply_um=" + getSokuji_aply_um());
		// ANK-4592-00-00 ADD END

		// サービス開始年月日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.svc_sta_ymd=" + getSvc_sta_ymd());

		// プラン開始年月日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.plan_staymd=" + getPlan_staymd());

		// プラン課金開始年月日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0065001.plan_chrg_staymd=" + plan_chrg_staymd);
	}

	/**
	 * <p>
	 * 基準日とする値を取得する。
	 * </p>
	 * @param retMap 相関ルール実行結果を格納したマップ
	 * @return 相関ルールの実行結果の基準日が「サービス開始日」の場合
	 *          相関ルール実行結果のサービス開始年月日を返す。
	 *          相関ルールの実行結果の基準日が「プラン開始日」の場合
	 *          相関ルール実行結果のプラン開始年月日を返す。
	 *          相関ルールの実行結果の基準日が「紐付く機器提供サービス契約のプラン開始日」の場合
	 *          相関ルール実行結果のプラン開始年月日を返す。
	 */
	private String getStdDate(HashMap<String, Object> retMap)
	{
		String sStdDate = null;

		// 実行結果の基準日が「サービス開始日」の場合
		if (STD_DT_KK0081_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 基準日にサービス開始年月日を設定する。
			sStdDate = getSvc_sta_ymd();
		}
		// 実行結果の基準日が「プラン開始日」の場合
		else if (STD_DT_KK0081_PLAN_STA.equals(retMap.get(STD_DT)))
		{
			// 基準日にプラン開始年月日を設定する。
			sStdDate = getPlan_staymd();
		}
		// 実行結果の基準日が「紐付く機器提供サービス契約のプラン開始年月日」の場合
		else if (STD_DT_KK0341_PLAN_STA.equals(retMap.get(STD_DT)))
		{
			// 個別検索条件マップ
			HashMap<String, String[]> searchJknMap = new HashMap<String, String[]>();
			// 追加検索条件：機器提供サービス契約.機器提供サービスコード = "ＳＴＢ"
			String [] kktkSvcCdList = {KKTK_SVC_CD_STB};
			searchJknMap.put(KK0341ETMsg.KKTK_SVC_CD, kktkSvcCdList);
			
			// サービス契約内訳番号に紐づく「機器提供サービス契約」(ＳＴＢ)を取得する
			JKKejbKK0341DBABase kk0341Dba = new JKKejbKK0341DBABase();
			CAANMsg[] kk0341MsgList = kk0341Dba.getKK0341bySvcKeiUcwk(getSvc_kei_ucwk_no(), searchJknMap, JKKModelCommon.getOpeDate(getCBSMsg()), "1");
			
			// 解約済、キャンセル済を除外する
			kk0341MsgList = kk0341Dba.getKK0341OutDsLCl(kk0341MsgList);
			
			// テレビの「サービス契約内訳」配下のSTBの「機器提供サービス契約」は必ず１件存在する。
			if (kk0341MsgList.length != 1)
			{
				throw new CAANRuntimeException("テレビの「サービス契約内訳」配下のSTBの「機器提供サービス契約」が０件、または複数件存在します。");
			}
			
			// 「機器提供サービス契約」(ＳＴＢ)のプラン開始年月日を基準日に設定する。
			sStdDate = kk0341MsgList[0].getString(KK0341ETMsg.PLAN_STAYMD);
		}

		return sStdDate;
	}

	/**
	 * <p>
	 * 基準日の翌月月初の値を返す。
	 * </p>
	 * @param sStdDate 基準日
	 * @return 基準日の翌月月初
	 */
	private String getBeginMonth(String sStdDate)
	{
		StringBuffer strBuf = new StringBuffer();
		
		String sNextMonthDate = "";

		try
		{
			// 基準日の翌月を算出する
			sNextMonthDate = JKKModelCommon.addMonth(sStdDate, 1);
		}
		catch (ParseException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 年月を抽出し、日付を1日に設定する
		strBuf.append(sNextMonthDate.substring(0, 6));
		strBuf.append(GESYO_SETTEI);

		return strBuf.toString();
	}

	/**
	 * <p>
	 * メンバ変数の申込明細番号に紐づく申込明細から申込番号を取得し
	 * 申込番号に紐づく申込明細の申込明細番号に紐づくサービス契約の
	 * サービス課金開始年月日を取得する。
	 * </p>
	 * @return 取得したサービス契約のサービス課金開始年月日を返す。
	 */
	private String getSvcChrgStaymd()
	{
		JSYejbDBAccess instance = null;
		String sSvcChrgStaymd = null;

		try
		{
			StringBuffer sql = new StringBuffer();
			sql.append(" SELECT ");
			sql.append("     KK0081.SVC_CHRG_STAYMD ");
			sql.append(" FROM ");
			sql.append("     KK_T_MSKM_DTL KK0021_01 ");
			sql.append("     INNER JOIN KK_T_MSKM_DTL KK0021_02 ");
			sql.append("     ON    KK0021_01.MSKM_NO = KK0021_02.MSKM_NO ");
			sql.append("     INNER JOIN KK_T_SVC_KEI KK0081 ");
			sql.append("     ON    KK0021_02.MSKM_DTL_NO = KK0081.MSKM_DTL_NO ");
			sql.append(" WHERE ");
			sql.append("     KK0021_01.MSKM_DTL_NO = ? ");
			sql.append(" AND (KK0021_01.MSKM_DTL_NO, KK0021_01.GENE_ADD_DTM) = ");
			sql.append("     (SELECT KK0021_01_GENE.MSKM_DTL_NO, MAX(KK0021_01_GENE.GENE_ADD_DTM) AS KK0021_01_MAX ");
			sql.append("      FROM   KK_T_MSKM_DTL KK0021_01_GENE ");
			sql.append("      WHERE  KK0021_01_GENE.MSKM_DTL_NO = KK0021_01.MSKM_DTL_NO ");
			sql.append("      AND    KK0021_01_GENE.MK_FLG = '0' ");
			sql.append("      GROUP BY KK0021_01_GENE.MSKM_DTL_NO) ");
			sql.append(" AND (KK0021_02.MSKM_DTL_NO, KK0021_02.GENE_ADD_DTM) = ");
			sql.append("     (SELECT KK0021_02_GENE.MSKM_DTL_NO, MAX(KK0021_02_GENE.GENE_ADD_DTM) AS KK0021_02_MAX ");
			sql.append("      FROM   KK_T_MSKM_DTL KK0021_02_GENE ");
			sql.append("      WHERE  KK0021_02_GENE.MSKM_DTL_NO = KK0021_02.MSKM_DTL_NO ");
			sql.append("      AND    KK0021_02_GENE.MK_FLG = '0' ");
			sql.append("      GROUP BY KK0021_02_GENE.MSKM_DTL_NO) ");
			sql.append(" AND KK0081.PRC_GRP_CD IN ('02', '03', '04') ");
			sql.append(" AND (KK0081.SVC_KEI_NO, KK0081.RSV_APLY_YMD || KK0081.GENE_ADD_DTM) =  ");
			sql.append("     (SELECT KK0081_GENE.SVC_KEI_NO, MAX(KK0081_GENE.RSV_APLY_YMD || KK0081_GENE.GENE_ADD_DTM) AS KK0081_MAX  ");
			sql.append("      FROM   KK_T_SVC_KEI KK0081_GENE  ");
			sql.append("      WHERE  KK0081_GENE.SVC_KEI_NO = KK0081.SVC_KEI_NO  ");
			sql.append("      AND    KK0081_GENE.RSV_APLY_YMD <= ?  ");
			sql.append("      AND    KK0081_GENE.RSV_APLY_CD = '2'  ");
			sql.append("      AND    KK0081_GENE.MK_FLG = '0' ");
			sql.append("      GROUP BY KK0081_GENE.SVC_KEI_NO) ");

			// SQLのログ出力
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), sql);

			// DBアクセスオブジェクトの生成
			instance = new JSYejbDBAccess(KK0021ETMsg.getTableName());
			instance.initialize();
			instance.prepareStatement(sql.toString());

			// パラメータの設定
			instance.setParam(getMskm_dtl_no());
			instance.setParam(JKKModelCommon.getOpeDate(getCBSMsg()));

			// SQLの実行
			instance.executeQuery();

			// 取得結果が存在する場合
			if (instance.next())
			{
				// サービス課金開始年月日を取得する。
				sSvcChrgStaymd = instance.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
			}
		}
		catch (SQLException sqle)
		{
			throw new CAANRuntimeException(sqle);
		}
		
		return sSvcChrgStaymd;
	}
}
