/*********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *  システム名		：eo顧客基幹システム
 *  モジュール名	：JKKejbKK0451Edit
 *  ソースファイル名：JKKejbKK0451Edit.java
 *  作成者			：富士通
 *  日付			：2011年10月17日
 *＜機能概要＞
 *  割引サービス契約編集共通部品クラス
 *＜修正履歴＞
 *  バージョン	修正日		修正者		修正内容
 *  v1.00.00	2011/10/17  富士通      新規作成
 *  v4.00.00    2013/07/16  FJ）寺園    IT1-2013-0001394
 *  v6.00.00    2013/12/16  FJ）寺園    OM-2013-0004207
 *  v8.00.00    2014/03/24  FJ）松枝    OM-2014-0000286
 *
 **********************************************************************/

package eo.ejb.common.edit;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANException;
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 com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;

import eo.common.util.JPCDateUtil;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0161ETMsg;
import eo.ejb.cbm.entity.KK0341ETMsg;
import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbm.entity.KK0401ETMsg;
import eo.ejb.cbm.entity.KK0441ETMsg;
import eo.ejb.cbm.entity.KK0451ETMsg;
import eo.ejb.cbm.entity.KK0481ETMsg;
import eo.ejb.cbm.entity.KK0481LE;
import eo.ejb.cbm.entity.KK0841ETMsg;
import eo.ejb.cbm.entity.KK2361ETMsg;
import eo.ejb.cbm.entity.KK2361LE;
import eo.ejb.cbm.entity.KK2371ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0451C020CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451C170CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451C220CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451D010CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.JKKejbBusinessException;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0161DBABase;
import eo.ejb.common.db.JKKejbKK0341DBABase;
import eo.ejb.common.db.JKKejbKK0351DBABase;
import eo.ejb.common.db.JKKejbKK0441DBABase;
import eo.ejb.common.db.JKKejbKK0451DBABase;
import eo.ejb.common.db.JKKejbKK0481DBABase;
import eo.ejb.common.db.JKKejbKK0841DBABase;
import eo.ejb.common.db.JKKejbKK2361DBABase;
import eo.ejb.common.db.JKKejbKK2371DBABase;
import eo.ejb.common.db.JKKejbOtherSysDBABase;
import eo.ejb.common.rule.JKKejbRule0089001;
import eo.ejb.common.rule.JKKejbRule0089002;

/**
 * <p>
 * 割引サービス契約世代登録年月日時分秒取得部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbKK0451Edit extends JKKejbKK0451DBABase
{

	/** 無効フラグ 有効 */
	private static final String MKFLG_VALID = "0";
	
	/** サービス課金終了年月日設定パターンコード：解約月末日 */
	public static final String CD01515_KAIYAKUDUKI_MATUJITU = "0";

	/** サービス課金終了年月日設定パターンコード：解約前月末日 */
	public static final String CD01515_KAIYAKUZENNGETU_MATUJITU = "1";

	/** サービス課金終了年月日設定パターンコード：解約日当日 */
	public static final String CD01515_KAIYAKUBI_TOUJITU = "2";

	/** サービス課金終了年月日設定パターンコード：CP解約日 */
	public static final String CD01515_CP_KAIYAKU_DAY = "3";
	
	/** 対象契約識別コード：サービス契約 */
	private static final String TG_KEI_SKBT_CD_SVCKEI = "01";

	/** 対象契約識別コード：サービス契約内訳 */
	private static final String TG_KEI_SKBT_CD_SVCKEIUCWK = "03";

	/** 対象契約識別コード：オプションサービス契約 */
	private static final String TG_KEI_SKBT_CD_OPSVCKEI = "04";
	
	/** 対象契約識別コード：サブオプションサービス契約 */
	private static final String TG_KEI_SKBT_CD_SBOPSVCKEI = "05";
	
	/** 対象契約識別コード：機器提供サービス契約 */
	private static final String TG_KEI_SKBT_CD_KIKITKSVCKEI = "06";
	
	/** 対象契約識別コード：請求オプションサービス契約 */
	private static final String TG_KEI_SKBT_CD_SKOPSVCKEI = "07";
	
	/** 契約ステータス：サービス提供中 */
	private static final String KEI_STAT_SVCTEIKYOTYU = "100";

	/** 割引解約キャンセル契機コード：自動設定 */
	private static final String WRIB_DSL_CNCL_OPTY_CD_AUTO = "1";

	/** 割引解約キャンセル契機コード：手動設定 */
	private static final String WRIB_DSL_CNCL_OPTY_CD_MANUAL  = "2";

	/** 料金スケジュール定義：基準日以降で直近の料金計算の請求年月 */
	private static final String AFTER_LATEST_SEIKYU_YM = "2";

	/** 接尾辞 */
	private static final String SUFFIX = "01";

	/** 割引タイプコード　32：長期継続利用割引 */
	private static final String WRIB_TYPE_CD_TYOUWARI = "32";
	
	/** 割引課金開始月指定コード：当月 */
	private static final String WRIB_CHRG_STA_MON_STI_CD_TG = "1";	

	/**
	 * コンストラクタです。
	 */
	public JKKejbKK0451Edit()
	{
	}

	/**
	 * <p>
	 * 割引サービス契約のカレントレコードの世代登録年月日時分秒を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return 指定された割引サービス契約番号に紐付くカレントレコードの世代登録年月日時分秒
	 */
	public Object getCurrentGeneAddDtm(CAANMsg inMsg, AgentDispatchContext inContext, Object wribSvcKeiNo)
	{
		// カレント検索用の割引サービス契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0451ETMsg.class.getName());
		inETMsg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsg.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 作成したメッセージを使用してカレント検索を行う
		CAANMsg otETMsg = super.findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == otETMsg)
		{
			return null;
		}

		return otETMsg.getString(KK0451ETMsg.GENE_ADD_DTM);
	}

	/**
	 * <p>
	 * 割引サービス契約のサービス課金終了年月日を編集します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return サービス課金終了年月日
	 */
	public Object getSvcChrgEndymd(CAANMsg inMsg, AgentDispatchContext inContext, Object wribSvcKeiNo)
	{

		// 割引サービス契約番号で一覧検索を行います
		CAANMsg inETMsgForCondition2361 = new CAANMsg(KK2361ETMsg.class.getName());
		inETMsgForCondition2361.set(KK2361ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsgForCondition2361.set(KK2361ETMsg.MK_FLG, MKFLG_VALID);
		KK2361LE le2361 = new KK2361LE();
		CAANMsg[] retConditionETMsg2361 = null;
		
		try
		{
			retConditionETMsg2361 = le2361.findByCondition(inETMsgForCondition2361);

			if (0 == retConditionETMsg2361.length)
			{
				// 対象レコードが存在しない場合
				return null;
			}

		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 運用日付の取得
		String opeDate = JKKModelCommon.getOpeDate(inMsg);
		
		// 割引解約キャンセル契機コードが未入力の場合
		if (inMsg.isNull(EKK0451C020CBSMsg.WRIB_DSL_CNCL_OPTY_CD))
		{
			throw new JKKejbBusinessException("割引解約キャンセル契機コードが未設定です。割引サービス契約番号 = [" + wribSvcKeiNo + " ]");
		}

		// 割引解約キャンセル契機コードを取得する
		String wribDslCnclOptyCd = inMsg.getString(EKK0451C020CBSMsg.WRIB_DSL_CNCL_OPTY_CD);

		// 料金スケジュール定義より料金計算日を元に請求年月を取得する
		JKKejbOtherSysDBABase jodba = new JKKejbOtherSysDBABase();
		String seikyuYm = jodba.getCH0501ByEventYmd(opeDate, AFTER_LATEST_SEIKYU_YM);

		// 請求年月が取得できなかった場合
		if (seikyuYm == null || seikyuYm.isEmpty())
		{
			throw new JKKejbBusinessException("料金スケジュール定義より請求年月が取得できませんでした。割引サービス契約番号 = [" + wribSvcKeiNo + " ]");
		}
		
		// 請求年月の前月末日を作る
		String seikyuYmd = seikyuYm.concat(SUFFIX);
		String seikyuYmdLastDay = JPCDateUtil.addDay(seikyuYmd, -1);

		String retWribSvcKeiUcwkNo = null;
		CAANMsg inETMsgForCurrent2361 = new CAANMsg(KK2361ETMsg.class.getName());
		CAANMsg inETMsgForCurrent2371 = new CAANMsg(KK2371ETMsg.class.getName());
		
		// 割引サービス契約内訳番号格納用マップ
		HashMap<String, String> escapeMap = new HashMap<String, String>();
		String svcChrgEndYmd = null;
		
		// サービス課金終了年月日保持用
		ArrayList<String> SvcChrgEndYmdList = new ArrayList<String>();

		// 一覧の結果を検索します
		for (int i = 0; i < retConditionETMsg2361.length; i++)
		{
			retWribSvcKeiUcwkNo = retConditionETMsg2361[i].getString(KK2361ETMsg.WRIB_SVC_KEI_UCWK_NO);
			
			if (escapeMap.containsKey(retWribSvcKeiUcwkNo))
			{
				// 既に検索済みの場合
				continue;
			}
			// 割引サービス契約内訳番号を格納します
			escapeMap.put(retWribSvcKeiUcwkNo, retWribSvcKeiUcwkNo);
			
			// 一覧結果の割引サービス契約内訳番号でカレント検索を行います
			inETMsgForCurrent2361.set(KK2361ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
			inETMsgForCurrent2361.set(KK2361ETMsg.WRIB_SVC_KEI_UCWK_NO, retWribSvcKeiUcwkNo);
			CAANMsg retCurrentETMsg2361 = new JKKejbKK2361DBABase().findByCurrent(inETMsgForCurrent2361);

			if (null == retCurrentETMsg2361)
			{
				// カレントレコードが存在しない場合
				continue;
			}
			
			// サービス課金終了年月日算出フラグが"0"の場合、入力のサービス課金終了年月日を設定する
			if ("0".equals(inMsg.getString(EKK0451C020CBSMsg.SVC_CHRG_ENDYMD_FLG)))
			{
				svcChrgEndYmd = inMsg.getString(EKK0451C020CBSMsg.SVC_CHRG_ENDYMD);
				SvcChrgEndYmdList.add(svcChrgEndYmd);
			}
			// サービス課金終了年月日算出フラグが"1"の場合、入力のサービス課金終了年月日を算出し設定する				
			else if ("1".equals(inMsg.getString(EKK0451C020CBSMsg.SVC_CHRG_ENDYMD_FLG)))
			{

				// 割引サービス契約内訳の割引サービス契約内訳番号でカレント検索されたデータから割引サービス詳細コード
				// を取得する
				String WribSvcDtlCd = retCurrentETMsg2361.getString(KK2361ETMsg.WRIB_SVC_DTL_CD);

				// 割引サービス詳細コードでカレント検索を行います
				inETMsgForCurrent2371.set(KK2371ETMsg.WRIB_SVC_DTL_CD, WribSvcDtlCd);
				CAANMsg retCurrentETMsg2371 = new JKKejbKK2371DBABase().findByCurrent(inETMsgForCurrent2371);

				// サービス課金終了年月日設定パターンコードによってサービス課金終了年月日の形式を変換する
				try
				{
					// 入力のサービス課金終了年月日をベースにサービス課金終了日を編集する
					svcChrgEndYmd = this.getSvcChrgEndYmd(retCurrentETMsg2371, inMsg.getString(EKK0451C020CBSMsg.SVC_CHRG_ENDYMD), wribDslCnclOptyCd, seikyuYmdLastDay);
					SvcChrgEndYmdList.add(svcChrgEndYmd);
				}
				catch (ParseException ex)
				{
					throw new CAANRuntimeException(ex);
				}
			}
		}
		
		// サービス課金終了年月日が最終日のものを返却する
		ArrayList<String> retSvcChrgEndYmd = new ArrayList<String>();

		// サービス課金終了年月日はnullがありうるのでnullは除外する
		for (int i = 0; i < SvcChrgEndYmdList.size(); i++)
		{
			// サービス課金終了年月日が未設定の場合は次に送る
			if (SvcChrgEndYmdList.get(i) == null || SvcChrgEndYmdList.get(i).isEmpty())
			{
				continue;
			}
			retSvcChrgEndYmd.add(SvcChrgEndYmdList.get(i));
		}
		// サービス課金終了年月日を昇順でソートする
		Collections.sort(retSvcChrgEndYmd);

		return retSvcChrgEndYmd.get(retSvcChrgEndYmd.size() - 1);
	}
	
	/**
	 * <p>
	 * サービス課金終了年月日設定パターンコード別にサービス課金終了年月日を算出する
	 * </p>
	 * @param kk2371ETMsg 割引サービス詳細
	 * @param baseYmd     サービス課金終了年月日
	 * @param wribDslCnclOptyCd 割引解約キャンセル契機コード
	 * @param seikyuYmd 料金スケジュールから算出した請求年月の前月末日
	 * @return　サービス課金終了年月日
	 * @throws ParseException 月の加減算処理にて、例外が発生した場合
	 */
	private String getSvcChrgEndYmd(CAANMsg kk2371ETMsg, String baseYmd, String wribDslCnclOptyCd, String seikyuYmd) throws ParseException
	{
		// サービス課金終了年月日設定パターンコードがnullの場合と割引サービス詳細コードに紐づくデータが
		// 割引サービス詳細に存在しない場合
		if (kk2371ETMsg == null || kk2371ETMsg.isNull(KK2371ETMsg.WRIB_SVC_DTL_CD))
		{
			return null; 
		}

		String retChgYmd = null;

		// サービス課金終了年月日設定パターンコードを取得する
		String svcChrgEndymdSetptnCd = kk2371ETMsg.getString(KK2371ETMsg.SVC_CHRG_ENDYMD_SETPTN_CD);

		// 	サービス課金終了年月日設定パターンコードが"解約月末日"の場合
		if (CD01515_KAIYAKUDUKI_MATUJITU.equals(svcChrgEndymdSetptnCd))
		{
			String ym = baseYmd.substring(0, 6);
			String lastDay = JPCDateUtil.getEndOfMonth(ym);
			retChgYmd = ym.concat(lastDay);
		}

		// サービス課金終了年月日設定パターンコードが"解約前月末日"の場合
		if (CD01515_KAIYAKUZENNGETU_MATUJITU.equals(svcChrgEndymdSetptnCd))
		{
			retChgYmd = this.getLastManthDay(baseYmd, -1);
		}
		
		// サービス課金終了年月日設定パターンコードが"解約日当日"の場合
		if (CD01515_KAIYAKUBI_TOUJITU.equals(svcChrgEndymdSetptnCd))
		{
			// ﾍﾞｰｽとなるサービス課金終了年月日を設定する
			retChgYmd = baseYmd;
		}

		// サービス課金終了年月日設定パターンコードが"CP解約日"の場合
		if (CD01515_CP_KAIYAKU_DAY.equals(svcChrgEndymdSetptnCd))
		{
			// 「割引解約キャンセル契機コード」が「1:自動設定」の場合
			if (WRIB_DSL_CNCL_OPTY_CD_AUTO.equals(wribDslCnclOptyCd))
			{
				String ym = baseYmd.substring(0, 6);
				String lastDay = JPCDateUtil.getEndOfMonth(ym);
				retChgYmd = ym.concat(lastDay);
			}
			// 「割引解約キャンセル契機コード」が「2:手動設定」の場合
			else if (WRIB_DSL_CNCL_OPTY_CD_MANUAL.equals(wribDslCnclOptyCd))
			{
				// 請求年月前月末日を設定する
				retChgYmd = seikyuYmd;
			}
		}
		// サービス課金終了年月日設定パターンコードが""の場合
		return retChgYmd;
	}

	/**
	 * <p>
	 * 対象の月の月末日を返却します
	 * </p>
	 * @param baseYmd 対象の年月日
	 * @param val 減算する月数
	 * @return 減算された月＋その月の末尾
	 */
	private String getLastManthDay(String baseYmd, int val)
	{
		String beforeYm = null;
		try
		{
			beforeYm = JPCDateUtil.addMonth(baseYmd, val).substring(0, 6);
		}
		catch (java.text.ParseException e)
		{
			e.printStackTrace();
		}
		String lastDay = JPCDateUtil.getEndOfMonth(beforeYm);
		return beforeYm.concat(lastDay);
	}
	
	/**
	 * <p>
	 * 割引サービス契約のカレントレコードを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return 指定された割引サービス契約番号に紐付くカレントレコード
	 */
	private CAANMsg getCurrentKK0451(CAANMsg inMsg, AgentDispatchContext inContext, Object wribSvcKeiNo)
	{
		// カレント検索用の割引サービス契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0451ETMsg.class.getName());
		inETMsg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsg.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 作成したメッセージを使用してカレント検索を行う
		CAANMsg otETMsg = super.findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == otETMsg)
		{
			return null;
		}

		return otETMsg;
	}
	
	/**
	 * <p>
	 * 割引サービス契約_サービス開始年月日を取得します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return サービス開始年月日
	 */
	public String getWribSvcStaYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日を取得する
		ArrayList<String> retList = this.getStaYmdAndChrgStaYmd(inMsg, inContext);

		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日が未設定の場合
		if (retList == null)
		{
			return null;
		}

		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日を取得
		String maxSvcStatYmd = retList.get(0);
		String mskmKisanYmd = retList.get(1);

		try
		{
			// 申込起算年月日 ≦ サービス開始年月日の最大日の場合
			if (mskmKisanYmd.compareTo(maxSvcStatYmd) <= 0)
			{
				// サービス開始年月日の最大日を返却する
				return maxSvcStatYmd;
			}
			// 申込起算年月日 > サービス開始年月日の最大日の場合
			else
			{
				// 申込起算年月日に＋1ヶ月する
				String nextMonth = JKKModelCommon.addMonth(mskmKisanYmd, 1);
				// 加算された年月日を年月のみに編集する
				String ym = nextMonth.substring(0, 6);
				// 申込起算年月日の翌月初日を返却する
				return ym.concat("01");
			}
		}
		catch (java.text.ParseException pe)
		{
			throw new CAANRuntimeException(pe);
		}
	}
	
	/**
	 * <p>
	 * 割引サービス契約_サービス課金開始年月日を取得します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return サービス課金開始年月日
	 */
	public String getWribSvcChrgStaYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日を取得する
		ArrayList<String> retList = this.getStaYmdAndChrgStaYmd(inMsg, inContext);

		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日が未設定の場合
		if (retList == null)
		{
			return null;
		}

		// 割引対象契約のサービス開始年月日の最大日と申込起算年月日を取得
		String maxSvcStatYmd = retList.get(0);
		String mskmKisanYmd = retList.get(1);

		try
		{
			// 申込起算年月日 ≦ サービス開始年月日の最大日の場合
			if (mskmKisanYmd.compareTo(maxSvcStatYmd) <= 0)
			{
				// サービス開始年月日の最大日に＋1ヶ月する
				String nextMonth = JKKModelCommon.addMonth(maxSvcStatYmd, 1);
				// 加算された年月日を年月のみに編集する
				String ym = nextMonth.substring(0, 6);
				// サービス開始年月日の翌月初日を返却する
				return ym.concat("01");
			}
			// 申込起算年月日 > サービス開始年月日の最大日の場合
			else
			{
				// 申込起算年月日に＋1ヶ月する
				String nextMonth = JKKModelCommon.addMonth(mskmKisanYmd, 1);
				// 加算された年月日を年月のみに編集する
				String ym = nextMonth.substring(0, 6);
				// 申込起算年月日の翌月初日を返却する
				return ym.concat("01");
			}
		}
		catch (java.text.ParseException pe)
		{
			throw new CAANRuntimeException(pe);
		}
	}
	
	/**
	 * <p>
	 * 割引サービス契約の開始年月日・課金開始年月日を編集します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 開始年月日・課金開始年月日
	 */
	private ArrayList<String> getStaYmdAndChrgStaYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		try
		{
			// 返却用リスト
			ArrayList<String> retList = new ArrayList<String>();
			
			// 割引サービス契約番号を取得します
			String wribSvcKeiNo = inMsg.getString(EKK0451C220CBSMsg.WRIB_SVC_KEI_NO);
			
			// 入力の割引サービス契約番号を元に割引サービス対象契約を全件検索する
			CAANMsg[] resKK0481 = this.getAllKK0481(inMsg, inContext, wribSvcKeiNo);

			// 検索結果が存在しない場合
			if (resKK0481 == null)
			{
				return null;
			}

			ArrayList<String> svcStatYmd = new ArrayList<String>();
			// 割引サービス対象契約番号格納
			ArrayList<String> WribSvcTrgtKeiNoList = new ArrayList<String>();
			
			// 全件検索結果を元にカレント情報を特定する
			for (int cnt = 0; resKK0481.length > cnt; cnt++)
			{
				// 割引サービス対象契約番号を取得します
				String WribSvcTrgtKeiNo = resKK0481[cnt].getString(KK0481ETMsg.WRIB_SVC_TRGT_KEI_NO);
				
				// 同一の割引サービス対象契約番号が出現した場合は次レコードへ進む
				if (WribSvcTrgtKeiNoList.contains(WribSvcTrgtKeiNo))
				{
					continue;
				}
				// これから検索する割引サービス対象契約番号をためる
				WribSvcTrgtKeiNoList.add(WribSvcTrgtKeiNo);
				
				// 割引対象サービス契約をカレント検索する
				CAANMsg KK0481Msg = this.getCurrentKK0481(inMsg, inContext, wribSvcKeiNo, WribSvcTrgtKeiNo);

				// 対象契約識別コードを元に親契約スキーマのカレントレコードを取得する
				CAANMsg currentData = this.getOyaKeiyakuInfo(inMsg, inContext, KK0481Msg);

				// 親契約の契約ステータスが"サービス提供中"以外の場合は次レコードに進む
				if (!this.isSvcStatChk(KK0481Msg, currentData))
				{
					continue;
				}
				// 各カレントレコードのサービス開始年月日を取得する
				svcStatYmd.add(this.getSvcStatYmd(KK0481Msg, currentData));
			}
			
			// サービス開始年月日の最大を取得する
			String maxSvcStatYmd = this.getMaxSvcStatYmd(svcStatYmd);
			
			// サービス開始年月日の最大が算出できなかった場合
			if(maxSvcStatYmd == null) {
				return null;
			}
			
			// 割引サービス契約のカレントレコードを取得する
			CAANMsg kk0451CurData = this.getCurrentKK0451(inMsg, inContext, wribSvcKeiNo);
			
			// 割引サービス契約のカレントレコードが取得できない場合
			if (kk0451CurData == null)
			{
				return null;
			}

			// 割引サービス契約のカレントレコードの申込起算年月日を取得する
			String mskmKisanYmd = kk0451CurData.getString(KK0451ETMsg.MSKM_KISAN_YMD);

			// 申込起算年月日が未設定の場合
			if (mskmKisanYmd == null)
			{
				return null;
			}
			
			// サービス開始年月日の最大日と申込起算年月日を返却する
			retList.add(0, maxSvcStatYmd);
			retList.add(1, mskmKisanYmd);
			
			return retList; 
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}
	}
	
	/**
	 * <p>
	 * サービス開始年月日の最大日を返却します
	 * </p>
	 * @param svcStatYmd サービス開始年月日のリスト
	 * @return サービス開始年月日の最大日
	 */
	private String getMaxSvcStatYmd(ArrayList<String> svcStatYmd)
	{
		// ソート用
		ArrayList<String> sortList = new ArrayList<String>();

		// サービス開始年月日が設定されている分繰り返し
		for (int cnt = 0; svcStatYmd.size() > cnt; cnt++)
		{
			// サービス開始年月日が未設定の場合は次レコードへ進む
			if (svcStatYmd.get(cnt) == null)
			{
				continue;
			}
			// ソート用リストに設定する
			sortList.add((String)svcStatYmd.get(cnt));
		}
		// サービス開始年月日を昇順にソートする
		Collections.sort(sortList);

		// 最大日を返却する
		return sortList.get(sortList.size() - 1);
	}
	
	/**
	 * <p>
	 * 対象契約識別コードを元に各種親契約スキーマのカレントレコードを取得します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param KK0481Msg 割引サービス対象契約の情報
	 * @return 各種親契約スキーマのカレントレコード
	 * @throws CAANException
	 */
	private CAANMsg getOyaKeiyakuInfo(CAANMsg inMsg, AgentDispatchContext inContext, CAANMsg KK0481Msg) throws CAANException
	{
		// 割引サービス対象契約のカレントレコードより「対象契約識別コード」を取得する
		String tgKeiSkbtCd = KK0481Msg.getString(KK0481ETMsg.TG_KEI_SKBT_CD);
		
		// 「対象契約識別コード」が未設定の場合
		if(tgKeiSkbtCd == null) {
			return null;
		}
		
		CAANMsg retCurrentRecord = null;
		// 対象契約識別コードを元に各サービス系のスキーマのカレントレコードを取得する
		if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEI))
		{
			// サービス契約よりカレントレコードを取得する
			retCurrentRecord = this.getCurrentKK0081(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.SVC_KEI_NO));
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEIUCWK))
		{
			// サービス契約内訳よりカレントレコードを取得する
			retCurrentRecord = this.getCurrentKK0161(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.SVC_KEI_UCWK_NO));
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_OPSVCKEI))
		{
			// オプションサービス契約よりカレントレコードを取得する
			retCurrentRecord = this.getCurrentKK0351(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.OP_SVC_KEI_NO));
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SBOPSVCKEI))
		{
			// サブオプションサービス契約番号しか設定されていない場合はオプションを特定してカレントを取得する
			retCurrentRecord = this.getCurrentKK0401(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.SBOP_SVC_KEI_NO));
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_KIKITKSVCKEI))
		{
			// 機器提供サービス契約よりカレントレコードを取得する
			retCurrentRecord = this.getCurrentKK0341(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.KKTK_SVC_KEI_NO));
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SKOPSVCKEI))
		{
			// 請求オプション契約よりカレントレコードを取得する
			retCurrentRecord = this.getCurrentKK0441(inMsg, inContext, KK0481Msg.getString(KK0481ETMsg.SEIOPSVC_KEI_NO));
		}
		return retCurrentRecord;
	}
	
	/**
	 * <p>
	 * 割引サービス対象契約を割引サービス契約番号をKEYに検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return 割引サービス契約番号に紐づいた割引サービス対象契約の情報
	 * @throws CAANException
	 */
	private CAANMsg[] getAllKK0481(CAANMsg inMsg, AgentDispatchContext inContext, String wribSvcKeiNo) throws CAANException
	{
		// 全件検索用の割引サービス対象契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0481ETMsg.class.getName());
		inETMsg.set(KK0481ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsg.set(KK0481ETMsg.MK_FLG, "0");

		CAANMsg[] outMsg = new KK0481LE().findByCondition(inETMsg);

		if (outMsg.length == 0)
		{
			return null;
		}
		return outMsg;
	}
	
	/**
	 * <p>
	 * 割引サービス対象契約のカレントレコードを取得します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @param WribSvcTrgtKeiNo 割引サービス対象契約番号
	 * @return 割引サービス対象契約のカレントレコード
	 */
	private CAANMsg getCurrentKK0481(CAANMsg inMsg, AgentDispatchContext inContext, String wribSvcKeiNo, String WribSvcTrgtKeiNo)
	{
		// カレント検索用の割引サービス対象契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0481ETMsg.class.getName());
		inETMsg.set(KK0481ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsg.set(KK0481ETMsg.WRIB_SVC_TRGT_KEI_NO, WribSvcTrgtKeiNo);

		// 作成したメッセージを使用してカレント検索を行う
		CAANMsg outMsg = new JKKejbKK0481DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == outMsg)
		{
			return null;
		}

		return outMsg;
	}
	
	/**
	 * <p>
	 * サブオプションサービス契約を全件検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param sbopSvcKeiNo サブオプションサービス契約番号
	 * @return サブオプションサービス契約番号に紐づいたサブオプションサービス契約の情報
	 * @throws CAANException
	 */
	private CAANMsg getCurrentKK0401(CAANMsg inMsg, AgentDispatchContext inContext, Object sbopSvcKeiNo)
	{
		// コネクション
		Connection con = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;

		// SQL文
		StringBuffer sbSql = new StringBuffer();
		sbSql.append(" SELECT  ")
			 .append("      KK0401.SVC_STAYMD  ")
			 .append("     ,KK0401.SBOP_SVC_KEI_STAT  ")
			 .append(" FROM  ")
			 .append("     KK_T_SBOP_SVC_KEI KK0401  ")
			 .append("     INNER JOIN KK_T_OP_SVC_KEI KK0351  ")
			 .append("     ON KK0401.OP_SVC_KEI_NO = KK0351.OP_SVC_KEI_NO  ")
			 .append(" WHERE  ")
			 .append("     KK0401.SBOP_SVC_KEI_NO = ?  ")
			 .append("     AND KK0401.SBOP_SVC_KEI_STAT = '100'  ")
			 .append("     AND (KK0401.OP_SVC_KEI_NO, KK0401.SBOP_SVC_KEI_NO, KK0401.RSV_APLY_YMD || KK0401.GENE_ADD_DTM) =  ")
			 .append("         (SELECT KK0401_GENE.OP_SVC_KEI_NO, KK0401_GENE.SBOP_SVC_KEI_NO, MAX(KK0401_GENE.RSV_APLY_YMD || KK0401_GENE.GENE_ADD_DTM) AS KK0401_MAX  ")
			 .append("          FROM   KK_T_SBOP_SVC_KEI KK0401_GENE   ")
			 .append("          WHERE  KK0401_GENE.OP_SVC_KEI_NO = KK0401.OP_SVC_KEI_NO   ")
			 .append("          AND    KK0401_GENE.SBOP_SVC_KEI_NO = KK0401.SBOP_SVC_KEI_NO   ")
			 .append("          AND    KK0401_GENE.RSV_APLY_YMD <= ?   ")
			 .append("          AND    KK0401_GENE.RSV_APLY_CD = '2'   ")
			 .append("          AND    KK0401_GENE.MK_FLG = '0'  ")
			 .append("          GROUP BY KK0401_GENE.OP_SVC_KEI_NO, KK0401_GENE.SBOP_SVC_KEI_NO)   ")
			 .append(" ORDER BY KK0401.SVC_STAYMD DESC ");

		try
		{

			//コネクション取得
			con = JSYejbConnection.getConnection(KK0401ETMsg.getTableName());

			//prepareStatementにSQL文をセット
			pstmt = con.prepareStatement(sbSql.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), sbSql);

			// バインド変数設定
			CAANJDBCUtil.setParam(pstmt, 1, sbopSvcKeiNo);
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			CAANMsg retMsg = new CAANMsg(KK0401ETMsg.class.getName());

			// 取得結果を格納（複数レコードが存在してもサービス開始日の最大がほしいので1件目のみ取得する）
			if (rsltQuery.next())
			{
				retMsg.set(KK0401ETMsg.SVC_STAYMD, rsltQuery.getString("SVC_STAYMD"));
				retMsg.set(KK0401ETMsg.SBOP_SVC_KEI_STAT, rsltQuery.getString("SBOP_SVC_KEI_STAT"));
			}

			return retMsg;
		}
		catch (SQLException e)
		{
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con != null)
				{
					CAANConnectionMgr.getInstance().close(con);
				}
			}
			catch (SQLException e)
			{
				throw new CAANRuntimeException(e);
			}
		}
	}

	/**
	 * <p>
	 * 契約ステータスが"サービス提供中"か否かを判定します
	 * </p>
	 * @param status
	 * @return true：サービス提供中 false：サービス提供中以外
	 */
	private boolean isSvcStatChk(CAANMsg KK0481Msg, CAANMsg currentData)
	{
		// 割引サービス対象契約のカレントレコードより「対象契約識別コード」を取得する
		String tgKeiSkbtCd = KK0481Msg.getString(KK0481ETMsg.TG_KEI_SKBT_CD);
		
		// 「対象契約識別コード」が未設定の場合
		if(tgKeiSkbtCd == null) {
			return false;
		}

		String status = null;
		// 対象契約識別コードを元に各サービス系スキーマのステータスを取得する
		if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEI))
		{
			// サービス契約よりステータスを取得する
			status = currentData.getString(KK0081ETMsg.SVC_KEI_STAT);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEIUCWK))
		{
			// サービス契約内訳よりステータスを取得する
			status = currentData.getString(KK0161ETMsg.SVC_KEI_UCWK_STAT);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_OPSVCKEI))
		{
			// オプションサービス契約よりステータスを取得する
			status = currentData.getString(KK0351ETMsg.OP_SVC_KEI_STAT);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SBOPSVCKEI))
		{
			// サブオプションサービス契約よりステータスを取得する
			status = currentData.getString(KK0401ETMsg.SBOP_SVC_KEI_STAT);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_KIKITKSVCKEI))
		{
			// 機器提供サービス契約よりステータスを取得する
			status = currentData.getString(KK0341ETMsg.KKTK_SVC_KEI_STAT);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SKOPSVCKEI))
		{
			// 請求オプション契約よりステータスを取得する
			status = currentData.getString(KK0441ETMsg.SEIOPSVC_KEI_STAT);
		}
		
		// 契約ステータスがサービス提供中か？
		if (KEI_STAT_SVCTEIKYOTYU.equals(status))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * <p>
	 * 各スキーマからサービス開始年月日を取得する
	 * </p>
	 * @param KK0481Msg 割引サービス対象契約のカレントレコード
	 * @param currentData 親契約スキーマのカレントレコード
	 * @return サービス開始年月日
	 */
	private String getSvcStatYmd(CAANMsg KK0481Msg, CAANMsg currentData)
	{
		// 割引サービス対象契約のカレントレコードより「対象契約識別コード」を取得する
		String tgKeiSkbtCd = KK0481Msg.getString(KK0481ETMsg.TG_KEI_SKBT_CD);
		
		// 「対象契約識別コード」が未設定の場合
		if(tgKeiSkbtCd == null) {
			return null;
		}

		String svcStatYmd = null;
		// 対象契約識別コードを元に各サービス系スキーマのステータスを取得する
		if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEI))
		{
			// サービス契約よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0081ETMsg.SVC_STA_YMD);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SVCKEIUCWK))
		{
			// サービス契約内訳よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0161ETMsg.SVC_STA_YMD);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_OPSVCKEI))
		{
			// オプションサービス契約よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0351ETMsg.SVC_STAYMD);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SBOPSVCKEI))
		{
			// サブオプションサービス契約よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0401ETMsg.SVC_STAYMD);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_KIKITKSVCKEI))
		{
			// 機器提供サービス契約よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0341ETMsg.SVC_STA_YMD);
		}
		else if (tgKeiSkbtCd.equals(TG_KEI_SKBT_CD_SKOPSVCKEI))
		{
			// 請求オプション契約よりサービス開始年月日を取得する
			svcStatYmd = currentData.getString(KK0441ETMsg.SVC_STA_YMD);
		}
		return svcStatYmd;
	}
	
	/**
	 * <p>
	 * 請求オプションサービス契約のカレントレコードを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param seiopsvcKeiNo 請求オプションサービス契約番号
	 * @return 指定された請求オプションサービス契約番号に紐付くカレントレコード
	 */
	private CAANMsg getCurrentKK0441(CAANMsg inMsg, AgentDispatchContext inContext, Object seiopsvcKeiNo)
	{
		// カレント検索用の請求オプションサービス契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0441ETMsg.class.getName());
		inETMsg.set(KK0441ETMsg.SEIOPSVC_KEI_NO, seiopsvcKeiNo);
		inETMsg.set(KK0441ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 作成したメッセージを使用してカレント検索を行う
		CAANMsg otETMsg = new JKKejbKK0441DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == otETMsg)
		{
			return null;
		}

		return otETMsg;
	}
	
	/**
	 * <p>
	 * サービス契約のカレントレコードの取得を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo 検索対象のサービス契約番号
	 * @return 指定されたサービス契約番号に紐付くカレントレコード
	 */
	private CAANMsg getCurrentKK0081(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// サービス契約のカレント検索を行う
		CAANMsg outETMsg = new JKKejbKK0081DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == outETMsg)
		{
			return null;
		}
		return outETMsg;
	}
	
	/**
	 * <p>
	 * サービス契約内訳のカレントレコードを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiucwkno 検索対象となるサービス契約内訳番号
	 * @return 指定されたサービス契約内訳番号に紐付くカレントレコード
	 */
	private CAANMsg getCurrentKK0161(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiucwkno)
	{

		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0161ETMsg.class.getName());
		inETMsg.set(KK0161ETMsg.SVC_KEI_UCWK_NO, svcKeiucwkno);
		inETMsg.set(KK0161ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// サービス契約内訳のカレント検索を行う
		CAANMsg ret0161C = new JKKejbKK0161DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == ret0161C)
		{
			return null;
		}
		return ret0161C;
	}
	
	/**
	 * <p>
	 * オプションサービス契約のカレントレコードの取得を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return 指定されたオプションサービス契約番号に紐付くカレントレコード
	 */
	public CAANMsg getCurrentKK0351(CAANMsg inMsg, AgentDispatchContext inContext, Object opSvcKeiNo)
	{
		// カレント検索用のオプションサービス契約の内部スキーマメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());
		inETMsg.set(KK0351ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		inETMsg.set(KK0351ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 作成したメッセージを使用してカレント検索を行う
		CAANMsg otETMsg = new JKKejbKK0351DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == otETMsg)
		{
			return null;
		}

		return otETMsg;
	}

	/**
	 * <p>
	 * 機器提供サービス契約のカレントレコードの取得を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kktksvckeino 検索対象となる機器提供サービス契約番号
	 * @return 指定された機器提供サービス契約番号に紐付くカレントレコード
	 */
	private CAANMsg getCurrentKK0341(CAANMsg inMsg, AgentDispatchContext inContext, Object kktksvckeino)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0341ETMsg.class.getName());
		inETMsg.set(KK0341ETMsg.KKTK_SVC_KEI_NO, kktksvckeino);
		inETMsg.set(KK0341ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 機器提供サービス契約のカレント検索を行う
		CAANMsg ret0341C = new JKKejbKK0341DBABase().findByCurrent(inETMsg);

		// 検索結果が0件の場合
		if (null == ret0341C)
		{
			return null;
		}

		return ret0341C;
	}

	/**
	 * <p>
	 * 割引サービス契約のサービス課金開始年月日を編集します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return サービス課金開始年月日
	 */
	public Object getSvcChrgStaymd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 返却用
		String svcChrgStaYmd = null;
		
		// 割引サービス契約番号を取得する
		String wribSvcKeiNo = inMsg.getString(EKK0451C170CBSMsg.WRIB_SVC_KEI_NO);
		// サービス課金開始年月日を取得する
		String inSvcChrgStaYmd = inMsg.getString(EKK0451C170CBSMsg.SVC_CHRG_STAYMD);

		// 割引適用基準日算出ルールを実行する
		JKKejbRule0089001 rule0089001 = new JKKejbRule0089001(inMsg);
		rule0089001.setWrib_svc_kei_no(wribSvcKeiNo);						// 割引サービス契約番号
		rule0089001.setWrib_amnt_snst_stdardymd(inSvcChrgStaYmd);		    // 割引額算出基準年月日

		try
		{
			// 割引適用基準年月日を取得する
			String wribTekioBaseYmd = rule0089001.getWribAmntSnstStdardYmd();

			// 割引適用基準年月日が取得できなかった場合
			if (wribTekioBaseYmd == null)
			{
				inMsg.set(EKK0451C170CBSMsg.SVC_CHRG_STAYMD_ERR, "EA");
				inMsg.set(JCMConstants.STATUS_INT_KEY, StatusCodes.TEMPLATE_CORRELATION_ERR);
			}

			// サービス課金開始年月日算出ルールを実行する
			JKKejbRule0089002 rule0089002 = new JKKejbRule0089002(inMsg);
			rule0089002.setWrib_svc_kei_no(wribSvcKeiNo);			// 割引サービス契約番号
			rule0089002.setWrib_tekio_stdardymd(wribTekioBaseYmd);	// 割引適用基準年月日
			
			svcChrgStaYmd = rule0089002.getWribAmntSnstStdardYmd();

			// サービス課金開始年月日が取得できなかった場合
			if (svcChrgStaYmd == null)
			{
				inMsg.set(EKK0451C170CBSMsg.SVC_CHRG_STAYMD_ERR, "EA");
				inMsg.set(JCMConstants.STATUS_INT_KEY, StatusCodes.TEMPLATE_CORRELATION_ERR);
			}
		}
		catch (java.text.ParseException pe)
		{
			throw new CAANRuntimeException("課金開始日設定定義(RULE0089)でエラーが発生しました。");
		}
		return svcChrgStaYmd;
	}
	
	/**
	 * <p>
	 * 割引課金開始月指定コードに設定する値を返却します
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 割引課金開始月指定コード
	 */
	public String getWribChrgStaMonStiCd(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// 割引課金開始月指定コードが設定されている場合
		if (!inCBSMsg.isNull(EKK0451D010CBSMsg.WRIB_CHRG_STA_MON_STI_CD))
		{
			return inCBSMsg.getString(EKK0451D010CBSMsg.WRIB_CHRG_STA_MON_STI_CD);
		}
		else
		{
			// 割引サービスコードをkeyに割引サービスマスタからカレントレコードを取得する
			CAANMsg kk0841cur = this.getKK0841byWribSvcCd(inCBSMsg.getString(EKK0451D010CBSMsg.WRIB_SVC_CD));

			// 検索結果が0件またはカレントレコードの割引タイプコードが未設定の場合
			if (kk0841cur == null || kk0841cur.isNull(KK0841ETMsg.WRIB_TYPE_CD))
			{
				return null;
			}

			// 割引タイプコードが"長期継続割引"の場合
			if (WRIB_TYPE_CD_TYOUWARI.equals(kk0841cur.getString(KK0841ETMsg.WRIB_TYPE_CD)))
			{
				return WRIB_CHRG_STA_MON_STI_CD_TG;
			}
			else
			{
				return null;
			}
		}
	}
	
	/**
	 * <p>
	 * 割引サービスコードをkeyに割引サービスﾏｽﾀのカレントレコードを取得します
	 * </p>
	 * @param wribSvcCd 割引サービスコード
	 * @return 割引サービスマスタカレントレコード
	 */
	private CAANMsg getKK0841byWribSvcCd(String wribSvcCd)
	{
		// 割引サービスのカレントレコードを取得する
		CAANMsg kk0841EtMsg = new CAANMsg(KK0841ETMsg.class.getName());
		kk0841EtMsg.set(KK0841ETMsg.WRIB_SVC_CD, wribSvcCd);
		kk0841EtMsg.set(KK0841ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(kk0841EtMsg));

		CAANMsg kk0841CurData = new JKKejbKK0841DBABase().findByCurrent(kk0841EtMsg);

		if (kk0841CurData == null)
		{
			return null;
		}

		return kk0841CurData;
	}

	/**
	 * <p>
	 * サービス提供中（解約前／休止中前）の項目値を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wribSvcKeiNo 割引サービス契約番号 
	 * @param wribSvcKeiStat 割引サービス契約ステータス 
	 * @param itemNm 項目名 
	 * @return 項目値
	 * @throws SQLException 
	 */
	public String getItemValueMae(CAANMsg inMsg, AgentDispatchContext inContext, Object wribSvcKeiNo, Object wribSvcKeiStat, Object itemNm) 
	{
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// 返却用変数
		String itemValue = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0451ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ");
			sql_Buff.append(itemNm);
			sql_Buff.append(" FROM   KK_T_WRIB_SVC_KEI KK0451 ");
			sql_Buff.append(" WHERE  KK0451.WRIB_SVC_KEI_NO = ? ");
			sql_Buff.append(" AND    (KK0451.WRIB_SVC_KEI_NO, KK0451.RSV_APLY_YMD || KK0451.GENE_ADD_DTM) = ");
			sql_Buff.append("        (SELECT KK0451_GENE.WRIB_SVC_KEI_NO, MAX(KK0451_GENE.RSV_APLY_YMD || KK0451_GENE.GENE_ADD_DTM) AS KK0451_MAX ");
			sql_Buff.append("         FROM   KK_T_WRIB_SVC_KEI KK0451_GENE ");
			sql_Buff.append("         WHERE  KK0451_GENE.WRIB_SVC_KEI_NO = KK0451.WRIB_SVC_KEI_NO ");
			sql_Buff.append("         AND    KK0451_GENE.WRIB_SVC_KEI_STAT = ? ");
			sql_Buff.append("         AND    KK0451_GENE.RSV_APLY_YMD <= ? ");
			sql_Buff.append("         AND    KK0451_GENE.RSV_APLY_CD = '2' ");
			sql_Buff.append("         AND    KK0451_GENE.MK_FLG = '0' ");
			sql_Buff.append("         GROUP BY KK0451_GENE.WRIB_SVC_KEI_NO) ");

			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(割引サービス契約番号)
			CAANJDBCUtil.setParam(pstmt, 1, wribSvcKeiNo);
			// パラメータの設定(割引サービス契約ステータス)
			CAANJDBCUtil.setParam(pstmt, 2, wribSvcKeiStat);
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// サービス課金終了年月日を取得する
			if (rsltQuery.next())
			{
				itemValue = rsltQuery.getString(itemNm.toString());
			}

		}
		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);
			}
		}
		return itemValue;
	}
	
	/**
	 * <p>
	 * 入力値が設定されていれば入力値を設定し、未設定時はカレントレコードの対象項目を取得します
	 * </p>
	 * @param wribSvcKeiNo 割引サービス契約番号 
	 * @param inValue 入力値 
	 * @param itemNm 項目名 
	 * @return 項目値
	 */
	public String getUpdNullItemValue(String wribSvcKeiNo, String inValue, String itemNm)
	{
		// 返却用変数
		String itemValue = inValue;
		
		// 入力値が未設定時
		if (inValue == null)
		{
			// 割引サービス契約のカレントレコードを取得する
			CAANMsg kk0451EtMsg = new CAANMsg(KK0451ETMsg.class.getName());
			kk0451EtMsg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
			kk0451EtMsg.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(kk0451EtMsg));

			CAANMsg kk0451CurData = new JKKejbKK0451DBABase().findByCurrent(kk0451EtMsg);

			if (kk0451CurData == null)
			{
				return null;
			}
			
			itemValue = kk0451CurData.getString(itemNm);
		}

		return itemValue;
	}
	/**
	 * <p>
	 * 割引サービス契約ステータスに応じてカレント引継を行うか判定します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param wribSvcKeiNo 検索対象の割引サービス契約番号
	 * @return 受付済、照査済、締結済であればfalse、それ以外の場合true
	 */
	public boolean isStatCurrent(CAANMsg inMsg, AgentDispatchContext inContext, Object wribSvcKeiNo)
	{
		
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0451ETMsg.class.getName());
		inETMsg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		inETMsg.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// 割引サービス契約のカレント検索を行う
		CAANMsg outETMsg = super.findByCurrent(inETMsg);
		
		if(outETMsg == null){
			return false;
		}

		String stat = outETMsg.getString(KK0451ETMsg.WRIB_SVC_KEI_STAT);
		
		if (JKKModelConst.WRIB_SVC_KEI_STAT_UK_ZM.equals(stat)) 
		{
			return false;
		}
		return true;
	}
}
