/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKejbKK0451KRCK
*   ソースファイル名：JKKejbKK0451KRCK.java
*   作成者          ：富士通
*   日付            ：2011年04月21日
*＜機能概要＞
*   割引サービス契約の関連制約部品クラス
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/04/21  富士通      新規作成
*   V5.00.00    2013/07/29  FJ）寺本    LT1-2013-0000654
*
**********************************************************************/

package eo.ejb.common.entity;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

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.fw.AgentDispatchContext;

import eo.common.util.JPCDateChecker;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0451ETMsg;
import eo.ejb.cbm.entity.KK0451LE;
import eo.ejb.cbm.entity.KK0481ETMsg;
import eo.ejb.cbm.entity.KK0481LE;
import eo.ejb.cbm.entity.KK0841ETMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.JKKejbCallTypeChecker;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0451DBABase;

/**
 * <p>
 * 割引サービス契約の関連制約部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbKK0451KRCK extends JKKejbKK0451DBABase
{
	/** サービスステータス（休止・中断中） */
	private static final String SVC_STAT_STOP = "210";

	/** サービスコード（インターネットサービス） */
	private static final String SVC_CD_INTER_NET_SVC = "01";

	/** 料金グループコード（eo光ネットホームタイプ） */
	private static final String PRC_GRP_CD_NET_HOME_TYPE = "02";

	/** 料金グループコード（eo光ネットメゾンタイプ） */
	private static final String PRC_GRP_CD_NET_MEZON_TYPE = "03";

	/** オプションサービスコード（Ｅメール） */
	private static final String OP_SVC_CD_EML = "B001";

	/** 割引サービスコード（ファミリーパック）*/
	private static final String WRIB_SVC_CD_FAMILY_PACK = "W00000006";

	/** 割引タイプコード（即割） */
	private static final String WRIB_TYPE_CD_SOKU_WARI = "31";

	/** 割引タイプコード（長割） */
	private static final String WRIB_TYPE_CD_NAGA_WARI = "30";

	/** 割引タイプコード（割賦契約割引） */
	private static final String WRIB_TYPE_CD_KAPP_KEI_WARI = "42";

	/** 割引サービス種別コード（置換型） */
	private static final String WRIB_SVC_SBT_CD_THIKAN = "01";

	/** 割引サービス契約ステータス(受付済) */
	private static final String WRIB_SVC_KEI_STAT_UKETSUKE = "010";

	/** 割引サービス契約ステータス(サービス提供中) */
	private static final String WRIB_SVC_KEI_STAT_SVC_KEI = "100";

	/** 無効フラグ（有効） */
	private static final String MK_FLG_YUKO = "0";

	/** 異動予約詳細コード（オプション開始） */
	private static final String IDO_RSV_DTL_OP_STA = "014";

	/** 異動予約詳細コード（オプション引継） */
	private static final String IDO_RSV_DTL_OP_SUCS = "015";

	/** オプションサービス契約_異動予約取得項目（異動予約詳細コード） **/
	private static final String SEL_OPIDO_IDO_DTL = "IDO_RSV_DTL_CD";

	/**
	 * <p>
	 * 新しいJKKejbKK0451KRCKを作成します。
	 * </p>
	 */
	public JKKejbKK0451KRCK()
	{
		super();
	}

	/**
	 * <p>
	 * サービス契約のステータスが休止中の場合、
	 * 判定対象日の未来日チェックを行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return boolean サービス契約が休止中かつ判定対象日が未来日の場合FALSE、それ以外の場合TRUE
	 */
	public boolean isValidDateInSvcStop(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 呼出先サービスが"バッチ"で"強制解約"のＪＯＢの場合
		if (JKKModelCommon.isBatOpeDateJobDsl())
		{
			// チェックを行わない
			return true;
		}

		KK0481LE leWariTgtKei = new KK0481LE();
		CAANMsg inWariTgtKei = new CAANMsg(KK0481ETMsg.class.getName());
		CAANMsg[] outWariTgtKei = null;

		inWariTgtKei.set(KK0481ETMsg.WRIB_SVC_KEI_NO, inMsg.getString(KK0481ETMsg.WRIB_SVC_KEI_NO));

		// 割引サービス対象契約を割引サービス契約番号で一覧照会
		try
		{
			outWariTgtKei = leWariTgtKei.findByCondition(inWariTgtKei);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException();
		}

		ArrayList<String> alSvcKeiNo = new ArrayList<String>();

		// サービス契約単位で集約(サービス契約番号がNULLの場合は集約しない)
		for (int i = 0; i < outWariTgtKei.length; i++)
		{
			boolean addFlg = true;
			String svcKeiNo = outWariTgtKei[i].getString(KK0481ETMsg.SVC_KEI_NO);
			if (!(svcKeiNo == null))
			{
				for (int j = 0; j < alSvcKeiNo.size(); j++)
				{
					// 集約済のサービス契約番号であれば、リストに追加しない
					if (svcKeiNo.equals(alSvcKeiNo.get(j)))
					{
						addFlg = false;
						break;
					}
				}
			}
			else
			{
				addFlg = false;
			}
			// まだリストにないサービス契約番号であれば、リストに追加する
			if (addFlg)
			{
				alSvcKeiNo.add(svcKeiNo);
			}
		}

		String baseDate = JKKModelCommon.getOpeDate(inMsg);
		JKKejbKK0081DBABase dbabSvcKei = new JKKejbKK0081DBABase();
		CAANMsg outSvcKei = null;

		// 集約したサービス契約番号単位でサービス契約を一意照会(カレント)
		for (int i = 0; i < alSvcKeiNo.size(); i++)
		{
			CAANMsg msgSvcKei = new CAANMsg(KK0081ETMsg.class.getName());
			msgSvcKei.set(KK0081ETMsg.SVC_KEI_NO, alSvcKeiNo.get(i));
			msgSvcKei.set(KK0081ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));
			outSvcKei = dbabSvcKei.findByCurrent(msgSvcKei);
			// サービス契約が休止中で、かつ判定対象日が未来日の場合、
			// falseを返却する
			if (SVC_STAT_STOP.equals(outSvcKei.getString(KK0081ETMsg.SVC_KEI_STAT)))
			{
				if (JPCDateChecker.isFutureDate(inMsg.getString(KK0451ETMsg.SVC_ENDYMD), baseDate, "0"))
				{
					return false;
				}
			}
		}
		// サービス契約が休止中でない、
		// またはサービス契約が休止中だが判定対象日が未来日でない場合、
		// trueを返却
		return true;
	}

	/**
	 * <p>
	 * 最大契約数のチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wariSvcCd 割引サービスコード
	 * @return 上限適用回数を超えない場合はtrue。上限値を超えた場合はfalse。
	 */
	public boolean isMaxKeiCnt(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		
		// フロントからの呼び出し以外の場合はチェックを行わない
		if (!JKKejbCallTypeChecker.isCallTypeFront(inContext))
		{
			return true;
		}
		
		// 割引サービスコードが"ファミリーパック"以外の場合、処理を終了する。
		if(!WRIB_SVC_CD_FAMILY_PACK.equals(inMsg.getString(KK0841ETMsg.WRIB_SVC_CD)))	
		{
			return true;
		}
		
		// 割引サービス契約の対象データ件数を取得
		long lDataCnt = getCountKK0451(inMsg, inContext, inMsg.getString(KK0451ETMsg.SYSID), inMsg.getString(KK0841ETMsg.WRIB_SVC_CD));
		
		// 割引サービスを取得
		String lUpplKeiCnt = getCountKK0841UpplAplyCnt(inMsg, inContext, inMsg.getString(KK0841ETMsg.WRIB_SVC_CD));
		
		// 上限適用回数がnullの場合、処理を終了する。
		if(lUpplKeiCnt == null)	
		{
			return true;
		}
		
		if(lDataCnt >= Long.parseLong(lUpplKeiCnt))
		{
			return false;
		}
		
		return true;
	}
	
	/**
	 * <p>
	 * 予約レコードにオプションサービスコードの("Eメール")の予約が存在するかチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号 
	 * @param wribSvcCd 割引サービスコード 
	 * @return オプションサービス契約が取得できた場合false、それ以外の場合true
	 */
	public boolean isMlMkm(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo, Object wribSvcCd)
	{
		// 割引タイプコードが"ファミリーパック"以外の場合、処理を終了する。
		if(!WRIB_SVC_CD_FAMILY_PACK.equals(wribSvcCd))	
		{
			return true;
		}
		
		// サービス契約番号に紐付くオプションサービス契約の予約を取得
		ArrayList<HashMap<String, String>> retKK0351 = new JKKejbKRCKCommon().getRsvOpIdoWithSvc(inMsg, inContext, svcKeiNo.toString(), OP_SVC_CD_EML);
		
		for (int i = 0; i < retKK0351.size(); i++)
		{
			HashMap<String, String> hash = retKK0351.get(i);
			
			// 「異動予約詳細コード」が
			// "014"（オプション開始）、"015"（オプション引継）いずれかである場合、falseを返却する
			if (IDO_RSV_DTL_OP_STA.equals(hash.get(SEL_OPIDO_IDO_DTL))
					|| IDO_RSV_DTL_OP_SUCS.equals(hash.get(SEL_OPIDO_IDO_DTL))) 
			{
				return false;
			}
		}

		// 対象の予約が存在しなかった場合はtrueを返却する
		return true;
	}
	
	/**
	 * <p>
	 * 「即割」が設定されているかチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号 
	 * @param wribSvcCd 割引サービスコード
	 * @return 割引タイプコードが"即割"：即割のレコードが存在しないチェックを行い、存在する場合false、存在しない場合trueを返却する。
	 */
	public boolean isSokuWariSvc(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo, Object wribSvcCd)
	{

		// サービス契約を検索し、状態をチェックする
		if(!isCheck(inMsg, svcKeiNo))
		{
			return true;
		}
					
		// 割引サービスを検索
		String wariTypeCode = getWariTypeCodeKK0841(inMsg, inContext, wribSvcCd);
						
		// 割引タイプコードが"即割"以外の場合、trueを返却する
		if(!WRIB_TYPE_CD_SOKU_WARI.equals(wariTypeCode))
		{
			return true;
		}
						
		// 全件検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0481ETMsg.class.getName());
		inETMsg.set(KK0481ETMsg.SVC_KEI_NO, svcKeiNo.toString());
		inETMsg.set(KK0481ETMsg.MK_FLG, MK_FLG_YUKO);

		
		// 割引サービス対象契約の全件検索を行う
		CAANMsg[] ret0481 = null;

		try
		{
			KK0481LE le = new KK0481LE();
			ret0481 = le.findByCondition(inETMsg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 検索結果が0件だった場合はtrueを返却
		if (ret0481.length == 0)
		{
			return true;
		}
		
		for(int i = 0; i < ret0481.length; i++)
		{
			// 割引サービス契約を検索
			CAANMsg ret451Msg = getWariSvcKeCurrent(inMsg, ret0481[i].getString(KK0481ETMsg.WRIB_SVC_KEI_NO));
			
			if(ret451Msg == null)
			{
				return true;
			}
			
			// カレント検索しレコードのステータスが「受付済」、「サービス提供中」以外であれば処理を終了する
			if(!WRIB_SVC_KEI_STAT_UKETSUKE.equals(ret451Msg.getString(KK0451ETMsg.WRIB_SVC_KEI_STAT)) 
					&& !WRIB_SVC_KEI_STAT_SVC_KEI.equals(ret451Msg.getString(KK0451ETMsg.WRIB_SVC_KEI_STAT)))
			{
				return true;
			}
			
			// 割引サービスを検索
			String wariTypeCodeCurrent = getWariTypeCodeKK0841(inMsg, inContext, ret451Msg.getString(KK0451ETMsg.WRIB_SVC_CD));
			
			if(WRIB_TYPE_CD_SOKU_WARI.equals(wariTypeCodeCurrent))
			{
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * <p>
	 * 「長割」が設定されているかチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号 
	 * @param wribSvcCd 割引サービスコード
	 * @return 割引タイプコードが"長割"：falseを返却する、それ以外ならtrueを返却する
	 */
	public boolean isNagaWariSvc(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo, Object wribSvcCd)
	{
		
		// フロントからの呼び出し以外の場合はチェックを行わない
		if (!JKKejbCallTypeChecker.isCallTypeFront(inContext))
		{
			return true;
		}

		// サービス契約を検索し、状態をチェックする
		if(!isCheck(inMsg, svcKeiNo))
		{
			return true;
		}
		
		// 割引サービスを検索
		String wariTypeCode = getWariTypeCodeKK0841(inMsg, inContext, wribSvcCd);
						
		// 割引タイプコードが"長割"以外の場合、trueを返却する
		if(WRIB_TYPE_CD_NAGA_WARI.equals(wariTypeCode))
		{
			return false;
		}
						
		return true;
	}
	
	/**
	 * <p>
	 * ファミリーパック割引の契約が存在しないかチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号 
	 * @param wribSvcCd 割引サービスコード 
	 * @return オプションサービス契約が取得できた場合false、それ以外の場合true
	 */
	public boolean isFamipaKeiZm(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo, Object wribSvcCd)
	{
		
		// 割引タイプコードが"ファミリーパック"以外の場合、処理を終了する。
		if(!WRIB_SVC_CD_FAMILY_PACK.equals(wribSvcCd))	
		{
			return true;
		}
		
		// 割引サービス契約の対象データ件数を取得
		long lDataCnt = getKeiCountKK0451(inMsg, inContext, svcKeiNo, wribSvcCd);
		
		// 存在する場合はfalseを返却
		if(lDataCnt > 0)
		{
			return false;
		}
				
		return true;
		
	}

	/**
	 * <p>
	 * サービス契約を検索し、関連制約を行うかチェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo サービス契約番号 
	 * @return 特定のサービスコード、料金グループ以外の場合false、それ以外true
	 */
	private boolean isCheck(CAANMsg inMsg, 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 ret0081 = new JKKejbKK0081DBABase().findByCurrent(inETMsg);
	
		if(ret0081 == null)
		{
			return true;
		}
		
		// 取得したサービス契約のサービスコードが"インターネットサービス"以外ならtrue
		if(!SVC_CD_INTER_NET_SVC.equals(ret0081.getString(KK0081ETMsg.SVC_CD)))
		{
			return false;
		}
		
		// 取得したサービス契約の料金グループコードが"eo光ネットホームタイプ"または"eo光ネットメゾンタイプ"以外ならtrue
		if(!PRC_GRP_CD_NET_HOME_TYPE.equals(ret0081.getString(KK0081ETMsg.PRC_GRP_CD)) 
				&& !PRC_GRP_CD_NET_MEZON_TYPE.equals(ret0081.getString(KK0081ETMsg.PRC_GRP_CD)))
		{
			return false;
		}
		
		return true;
	}
	
	/**
	 * <p>
	 * 割引サービス契約を検索し、割引サービス契約のカレントレコードを取得する。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param wrivSvcKeiNo 割引サービス契約番号
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 割引サービス契約のカレントレコード
	 */
	private CAANMsg getWariSvcKeCurrent(CAANMsg inMsg, Object wrivSvcKeiNo)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inKK0451 = new CAANMsg(KK0451ETMsg.class.getName());
		inKK0451.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wrivSvcKeiNo);
		inKK0451.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));
		
		// 割引サービス契約のカレント検索を行う
		CAANMsg ret0451 = new JKKejbKK0451DBABase().findByCurrent(inKK0451);
		
		return ret0451;
	}
	
	/**
	 * <p>
	 * 割引サービス契約のデータを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param sysid SYSID 
	 * @param waibSvcCd 割引サービスコード
	 * @return オプションサービス契約のデータ件数
	 */
	private long getCountKK0451(CAANMsg inMsg, AgentDispatchContext inContext, Object sysid, Object waibSvcCd)
	{
	
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
	
		long lDataCnt = 0L;
	
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0451ETMsg.getTableName());
	
			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append("SELECT ")
					.append("    COUNT(*) AS CNT ")
					.append("FROM ")
					.append("    KK_T_WRIB_SVC_KEI KK0451, ")
					.append("	 (SELECT ")
					.append("    	WRIB_SVC_CD ")
					.append("	  FROM ")
					.append("    	KK_M_WRIB_SVC ")					
					.append("	  WHERE ")
					.append("    	KK_M_WRIB_SVC.WRIB_SVC_CD = 'W00000006' ")
					.append("      	AND    KK_M_WRIB_SVC.WRIB_SVC_TSTAYMD <= ? ")
					.append("      	AND    KK_M_WRIB_SVC.WRIB_SVC_TENDYMD >= ? ")
					.append("    	AND (KK_M_WRIB_SVC.WRIB_SVC_CD, KK_M_WRIB_SVC.RSV_APLY_YMD || KK_M_WRIB_SVC.GENE_ADD_DTM) = ")
					.append("        	(SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
					.append("         	FROM   KK_M_WRIB_SVC KK0841_GENE ")
					.append("         	WHERE  KK0841_GENE.WRIB_SVC_CD = KK_M_WRIB_SVC.WRIB_SVC_CD ")
					.append("         	AND    KK0841_GENE.RSV_APLY_YMD <= ? ")
					.append("         	AND    KK0841_GENE.MK_FLG= '0' ")
					.append("         	GROUP BY KK0841_GENE.WRIB_SVC_CD)) KK0841 ")
					.append("WHERE ")
					.append("    KK0451.SYSID = ? ")
					.append("    AND KK0451.WRIB_SVC_KEI_STAT IN ('010', '100', '300') ")
					.append("    AND KK0451.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
					.append("    AND (KK0451.WRIB_SVC_KEI_NO, KK0451.RSV_APLY_YMD || KK0451.GENE_ADD_DTM) = ")
					.append("        (SELECT KK0451_GENE.WRIB_SVC_KEI_NO, MAX(KK0451_GENE.RSV_APLY_YMD || KK0451_GENE.GENE_ADD_DTM) AS KK0451_MAX ")
					.append("         FROM   KK_T_WRIB_SVC_KEI KK0451_GENE ")
					.append("         WHERE  KK0451_GENE.WRIB_SVC_KEI_NO = KK0451.WRIB_SVC_KEI_NO ")
					.append("         AND    ((KK0451_GENE.RSV_APLY_CD = '1' AND KK0451_GENE.RSV_APLY_YMD > ? ) OR KK0451_GENE.RSV_APLY_CD = '2') ")
					.append("         AND    KK0451_GENE.MK_FLG= '0' ")
					.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, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));
			// パラメータの設定(sysidを指定)
			CAANJDBCUtil.setParam(pstmt, 4, sysid);
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 5, JKKModelCommon.getOpeDate(inMsg));
	
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
	
			// 件数を返却する
			if (rsltQuery.next())
			{
				lDataCnt = rsltQuery.getLong("CNT");
			}
	
		}
		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 lDataCnt;
	}
	
	/**
	 * <p>
	 * 割引サービス契約の契約数を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号
	 * @param waibSvcCd 割引サービスコード
	 * @return 割引サービス契約の契約数
	 */
	private long getKeiCountKK0451(CAANMsg inMsg, AgentDispatchContext inContext, Object svcKeiNo, Object waibSvcCd)
	{
	
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
	
		long lDataCnt = 0L;
	
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0451ETMsg.getTableName());
	
			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append("SELECT ")
					.append("    COUNT(*) AS CNT ")
					.append("FROM ")
					.append("    KK_T_WRIB_SVC_KEI KK0451, ")
					.append("	 (SELECT ")
					.append("    	WRIB_SVC_KEI_NO ")
					.append("	  FROM ")
					.append("    	KK_T_WRISVC_TG_KEI KK0481 ")					
					.append("	  WHERE ")
					.append("    	KK0481.SVC_KEI_NO = ? ")
					.append("    	AND KK0481.TG_KEI_SKBT_CD = '01' ")
					.append("    	AND (KK0481.WRIB_SVC_KEI_NO, KK0481.WRIB_SVC_TRGT_KEI_NO, KK0481.GENE_ADD_DTM) = ")
					.append("        	(SELECT KK0481_GENE.WRIB_SVC_KEI_NO, KK0481_GENE.WRIB_SVC_TRGT_KEI_NO, MAX(KK0481_GENE.GENE_ADD_DTM) AS KK0481_MAX ")
					.append("         	FROM   KK_T_WRISVC_TG_KEI KK0481_GENE ")
					.append("         	WHERE  KK0481_GENE.WRIB_SVC_KEI_NO = KK0481.WRIB_SVC_KEI_NO ")
					.append("         	AND    KK0481_GENE.WRIB_SVC_TRGT_KEI_NO = KK0481.WRIB_SVC_TRGT_KEI_NO ")
					.append("         	AND    KK0481_GENE.MK_FLG= '0' ")
					.append("         	GROUP BY KK0481_GENE.WRIB_SVC_KEI_NO, KK0481_GENE.WRIB_SVC_TRGT_KEI_NO)) KK0481, ")
					.append("	 (SELECT ")
					.append("    	WRIB_SVC_CD ")
					.append("	  FROM ")
					.append("    	KK_M_WRIB_SVC ")					
					.append("	  WHERE ")
					.append("    	KK_M_WRIB_SVC.WRIB_SVC_CD = 'W00000006' ")
					.append("      	AND    KK_M_WRIB_SVC.WRIB_SVC_TSTAYMD <= ? ")
					.append("      	AND    KK_M_WRIB_SVC.WRIB_SVC_TENDYMD >= ? ")
					.append("    	AND (KK_M_WRIB_SVC.WRIB_SVC_CD, KK_M_WRIB_SVC.RSV_APLY_YMD || KK_M_WRIB_SVC.GENE_ADD_DTM) = ")
					.append("        	(SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
					.append("         	FROM   KK_M_WRIB_SVC KK0841_GENE ")
					.append("         	WHERE  KK0841_GENE.WRIB_SVC_CD = KK_M_WRIB_SVC.WRIB_SVC_CD ")
					.append("         	AND    KK0841_GENE.RSV_APLY_YMD <= ? ")
					.append("         	AND    KK0841_GENE.MK_FLG= '0' ")
					.append("         	GROUP BY KK0841_GENE.WRIB_SVC_CD)) KK0841 ")
					.append("WHERE ")
					.append("    KK0451.WRIB_SVC_KEI_NO = KK0481.WRIB_SVC_KEI_NO ")				
					.append("    AND KK0451.WRIB_SVC_KEI_STAT IN ('010', '100', '300') ")
					.append("    AND KK0451.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
					.append("    AND (KK0451.WRIB_SVC_KEI_NO, KK0451.RSV_APLY_YMD || KK0451.GENE_ADD_DTM) = ")
					.append("        (SELECT KK0451_GENE.WRIB_SVC_KEI_NO, MAX(KK0451_GENE.RSV_APLY_YMD || KK0451_GENE.GENE_ADD_DTM) AS KK0451_MAX ")
					.append("         FROM   KK_T_WRIB_SVC_KEI KK0451_GENE ")
					.append("         WHERE  KK0451_GENE.WRIB_SVC_KEI_NO = KK0451.WRIB_SVC_KEI_NO ")
					.append("         AND    ((KK0451_GENE.RSV_APLY_CD = '1' AND KK0451_GENE.RSV_APLY_YMD > ? ) OR KK0451_GENE.RSV_APLY_CD = '2') ")
					.append("         AND    KK0451_GENE.MK_FLG= '0' ")
					.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, svcKeiNo);
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 4, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 5, JKKModelCommon.getOpeDate(inMsg));
	
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
	
			// 件数を返却する
			if (rsltQuery.next())
			{
				lDataCnt = rsltQuery.getLong("CNT");
			}
	
		}
		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 lDataCnt;
	}

	/**
	 * <p>
	 * 割引サービスの上限適用回数を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param warbSvcCd 対象の割引サービスコード
	 * @return 割引サービスの上限適用回数
	 */
	private String getCountKK0841UpplAplyCnt(CAANMsg inMsg, AgentDispatchContext inContext, Object warbSvcCd)
	{
	
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
	
		String lDataCnt = null;
	
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0841ETMsg.getTableName());
	
			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append("SELECT ")
					.append("    KK0841.UPPL_APLY_CNT ")
					.append("FROM ")
					.append("    KK_M_WRIB_SVC KK0841 ")
					.append("WHERE ")
					.append("    KK0841.WRIB_SVC_CD = ? ")
					.append("    AND KK0841.WRIB_SVC_TSTAYMD <= ? ")
					.append("    AND KK0841.WRIB_SVC_TENDYMD >= ? ")
					.append("    AND (KK0841.WRIB_SVC_CD, KK0841.RSV_APLY_YMD || KK0841.GENE_ADD_DTM) = ")
					.append("        (SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
					.append("         FROM   KK_M_WRIB_SVC KK0841_GENE  ")
					.append("         WHERE  KK0841_GENE.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
					.append("         AND KK0841_GENE.RSV_APLY_YMD <= ? ")
					.append("         AND KK0841_GENE.MK_FLG= '0' ")
					.append("         GROUP BY KK0841_GENE.WRIB_SVC_CD) ");
				
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
	
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);
	
			// パラメータの設定(割引サービスコード)を指定
			CAANJDBCUtil.setParam(pstmt, 1, warbSvcCd);
			
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 4, JKKModelCommon.getOpeDate(inMsg));
	
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
	
			// 上限適用回数を返却する
			if (rsltQuery.next())
			{
				lDataCnt = rsltQuery.getString("UPPL_APLY_CNT");
			}
	
		}
		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 lDataCnt;
	}
		
	/**
	 * <p>
	 * 割引サービス割引タイプコードのデータを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wariSvcCd 対象の割引サービスコード
	 * @return オプションサービス契約のデータ件数
	 */
	private String getWariTypeCodeKK0841(CAANMsg inMsg, AgentDispatchContext inContext, Object wariSvcCd)
	{
	
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
	
		String wariTypeCode = null;
	
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0841ETMsg.getTableName());
	
			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append("SELECT ")
					.append("    KK0841.WRIB_TYPE_CD ")
					.append("FROM ")
					.append("    KK_M_WRIB_SVC KK0841 ")
					.append("WHERE ")
					.append("    KK0841.WRIB_SVC_CD = ? ")
					.append("    AND KK0841.WRIB_SVC_TSTAYMD <= ? ")
					.append("    AND KK0841.WRIB_SVC_TENDYMD >= ? ")
					.append("    AND (KK0841.WRIB_SVC_CD, KK0841.RSV_APLY_YMD || KK0841.GENE_ADD_DTM) = ")
					.append("        (SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
					.append("         FROM   KK_M_WRIB_SVC KK0841_GENE  ")
					.append("         WHERE  KK0841_GENE.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
					.append("         AND KK0841_GENE.RSV_APLY_YMD <= ? ")
					.append("         AND KK0841_GENE.MK_FLG= '0' ")
					.append("         GROUP BY KK0841_GENE.WRIB_SVC_CD) ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
	
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);
	
			// パラメータの設定(割引サービスコードを指定)
			CAANJDBCUtil.setParam(pstmt, 1, wariSvcCd);
			
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 4, JKKModelCommon.getOpeDate(inMsg));
	
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
	
			// 件数を返却する
			if (rsltQuery.next())
			{
				wariTypeCode = rsltQuery.getString("WRIB_TYPE_CD");
			}
	
		}
		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 wariTypeCode;
	}
	
	/**
	 * <p>
	 * 割引タイプコードが"割賦契約割引"か否かを判定する
	 * </p>
	 * @param inETMsg    処理対象のメッセージキャリア
	 * @param inContext  Agentから渡されたAgentDispatchContext
	 * @return true：割賦契約割引 false：割賦契約割引でない
	 */
	public boolean isWribSvcTypeCdChecker(CAANMsg inETMsg, AgentDispatchContext inContext)
	{
		// 割引サービス契約番号が未設定の場合、正常とする
		if (inETMsg.isNull(KK0451ETMsg.WRIB_SVC_KEI_NO))
		{
			return true;
		}

		// 割引サービス契約番号をKEYに割引サービス契約のカレントレコードを取得する
		CAANMsg retKK0451Cur = this.getWariSvcKeCurrent(inETMsg, inETMsg.getString(KK0451ETMsg.WRIB_SVC_KEI_NO));

		// 割引サービス契約の検索結果が0件の場合、falseを返却する
		if (retKK0451Cur == null)
		{
			return false;
		}

		// 割引サービスコードが未設定の場合、falseを返却する
		if (retKK0451Cur.isNull(KK0451ETMsg.WRIB_SVC_CD))
		{
			return false;
		}

		// 割引サービスから割引サービスコードをKEYに割引タイプコードを取得する
		String wribTypeCd = this.getWariTypeCodeKK0841(inETMsg, inContext, retKK0451Cur.getString(KK0451ETMsg.WRIB_SVC_CD));

		// 割引タイプコードが"割賦契約割引"以外の場合、エラーを返却
		if (!WRIB_TYPE_CD_KAPP_KEI_WARI.equals(wribTypeCd))
		{
			return false;
		}
		return true;
	}
	
	/**
	 * <p>
	 * 割引サービス種別コードが"置換型"か否かを判定する	 
	 * </p>
	 * @param inETMsg    処理対象のメッセージキャリア
	 * @param inContext  Agentから渡されたAgentDispatchContext
	 * @return true：置換型 false：置換型でない
	 */
	public boolean isWribSvcSbtCdTikan(CAANMsg inETMsg, AgentDispatchContext inContext)
	{
		// 割引サービス契約番号が未設定の場合、正常とする
		if (inETMsg.isNull(KK0451ETMsg.WRIB_SVC_KEI_NO))
		{
			return true;
		}

		// 割引サービス契約番号をKEYに割引サービス契約のカレントレコードを取得する
		CAANMsg retKK0451Cur = this.getWariSvcKeCurrent(inETMsg, inETMsg.getString(KK0451ETMsg.WRIB_SVC_KEI_NO));

		// 割引サービス契約の検索結果が0件の場合、falseを返却する
		if (retKK0451Cur == null)
		{
			return false;
		}

		// 割引サービスコードが未設定の場合、falseを返却する
		if (retKK0451Cur.isNull(KK0451ETMsg.WRIB_SVC_CD))
		{
			return false;
		}

		// 割引サービスから割引サービスコードをKEYに割引サービス種別コードを取得する
		String wribSvcSbtCd = this.getWariSvcSbtCodeKK0841(inETMsg, inContext, retKK0451Cur.getString(KK0451ETMsg.WRIB_SVC_CD));

		// 割引サービス種別コードが"置換型"以外の場合、エラーを返却
		if (!WRIB_SVC_SBT_CD_THIKAN.equals(wribSvcSbtCd))
		{
			return false;
		}
		return true;
	}
	
	/**
	 * <p>
	 * 割引サービスの割引サービス種別コードのデータを取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param wariSvcCd 対象の割引サービスコード
	 * @return 割引サービス種別コード
	 */
	private String getWariSvcSbtCodeKK0841(CAANMsg inMsg, AgentDispatchContext inContext, Object wariSvcCd)
	{
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// 割引サービス種別コードを格納する
		String wribSvcSbtCd = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0841ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append("SELECT ")
					.append("    KK0841.WRIB_SVC_SBT_CD  ")
					.append("FROM ")
					.append("    KK_M_WRIB_SVC KK0841 ")
					.append("WHERE ")
					.append("    KK0841.WRIB_SVC_CD = ? ")
					.append("    AND KK0841.WRIB_SVC_TSTAYMD <= ? ")
					.append("    AND KK0841.WRIB_SVC_TENDYMD >= ? ")
					.append("    AND (KK0841.WRIB_SVC_CD, KK0841.RSV_APLY_YMD || KK0841.GENE_ADD_DTM) = ")
					.append("        (SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
					.append("         FROM   KK_M_WRIB_SVC KK0841_GENE  ")
					.append("         WHERE  KK0841_GENE.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
					.append("         AND KK0841_GENE.RSV_APLY_YMD <= ? ")
					.append("         AND KK0841_GENE.MK_FLG= '0' ")
					.append("         GROUP BY KK0841_GENE.WRIB_SVC_CD) ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(割引サービスコードを指定)
			CAANJDBCUtil.setParam(pstmt, 1, wariSvcCd);

			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 3, JKKModelCommon.getOpeDate(inMsg));
			CAANJDBCUtil.setParam(pstmt, 4, JKKModelCommon.getOpeDate(inMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// 割引サービス種別コードを返却する
			if (rsltQuery.next())
			{
				wribSvcSbtCd = rsltQuery.getString("WRIB_SVC_SBT_CD");
			}
		}
		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 wribSvcSbtCd;
	}
	
	/**
	 * <p>
	 * 割引サービス契約の存在チェックを行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージ
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return カレントレコードが存在する場合はtrue
	 */
	public boolean isExists(CAANMsg inMsg, String wribSvcKeiNo)
	{
		if (wribSvcKeiNo == null)
		{
			return true;
		}

		// カレントレコード検索パラメータの設定
		CAANMsg msg = new CAANMsg(KK0451ETMsg.class.getName());
		msg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		msg.set(KK0451ETMsg.MK_FLG, "0");

		// ロジカルエンティティ生成
		KK0451LE le = new KK0451LE();
		try
		{
			CAANMsg[] rsltList = le.findByCondition(msg);

			//存在しない場合
			if (rsltList.length == 0)
			{
				return false;
			}

			//存在する場合
			return true;
		}
		catch (CAANException ex)
		{
			throw new CAANRuntimeException(ex);
		}
	}
	
	/**
	 * <p>
	 * 割引サービス契約のプライマリレコードの存在チェックを行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージ
	 * @param wribSvcKeiNo 割引サービス契約番号
	 * @return カレントレコードが存在する場合はtrue
	 */
	public boolean isExistsPrimary(CAANMsg inMsg, String wribSvcKeiNo, String geneAddDtm)
	{
		if (wribSvcKeiNo == null || geneAddDtm == null)
		{
			return true;
		}
		
		// プライマリレコード検索パラメータの設定
		CAANMsg searchKey = new CAANMsg(KK0451ETMsg.class.getName());
		searchKey.set(KK0451ETMsg.WRIB_SVC_KEI_NO, wribSvcKeiNo);
		searchKey.set(KK0451ETMsg.GENE_ADD_DTM, geneAddDtm);
		
		CAANMsg outMsg1 = new KK0451LE().findByPrimaryKey(searchKey);
		
		// 検索結果が未設定または無効フラグが"無効"の場合
		if (outMsg1 == null 
				|| JKKModelConst.MK_FLG_MK.equals(outMsg1.getString(KK0451ETMsg.MK_FLG)))
		{
			return false;
		}
		
		//存在する場合
		return true;
	}
}