/*********************************************************************
 *   All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：JKKejbKK0341KRCK
 *  ソースファイル名：JKKejbKK0341KRCK.java
 *  作成者          ：富士通
 *  日付            ：2011年04月20日
 *＜機能概要＞
 *  機器提供サービス契約の関連制約部品クラス
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v1.00.00    2011/04/20  富士通      新規作成
 *  v4.00.00    2013/01/22	FJ)坂本     ST1-2012-000084600
 *  v5.00.00    2013/02/04  FJ)沖田     ANK-1402-00-00対応
 *  v5.00.01    2013/03/02  FJ)寺園     IT1-2013-0000186
 *  v5.00.02    2013/03/18  FJ)沖田     ANK-1429-00-00
 *  v5.00.03    2013/08/06  FJ)寺園     IT2-2013-0000677
 *  v5.00.04    2013/08/30  FJ)竹内     OM-2013-0001039
 *  v5.00.05    2013/10/03  FJ)寺園     OM-2013-0002733
 *  v5.00.06    2013/11/19  FJ)寺園     OM-2013-0004204
 *  v7.00.00    2013/12/08  FJ)大山     ANK-1578-00-00
 *  v7.00.01    2013/12/19  FJ)小島     ANK-1578-00-00
 *  v7.00.02    2013/12/24  FJ)松枝     ANK-1578-00-00
 *  v6.00.00    2013/12/28  FJ)大山     OM-2013-0005389
 *  v7.00.03    2013/12/30  FJ)大山     IT1-2013-0001748
 *  v7.00.04    2014/01/05  FJ)大山     IT1-2013-0001748
 *  v7.00.05    2014/01/15  FJ)寺園     IT1-2014-0000024
 *  v8.00.00    2014/03/25  FJ)寺園     IT2-2014-0000171
 *  v8.00.01    2014/04/01  FJ)寺園     IT2-2014-0000171（追加修正）
 *  v8.00.02	2014/05/16	FJ)宇野		OM-2014-0001528
 * v61.00.00	2023/06/29  FJ)澤田	   【ANK-4315-00-00】【eo定期】eoホームゲートウェイ導入対応
 **********************************************************************/

package eo.ejb.common.entity;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
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.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0241ETMsg;
import eo.ejb.cbm.entity.KK0341ETMsg;
import eo.ejb.cbm.entity.KK0341LE;
import eo.ejb.cbm.entity.KK0801ETMsg;
import eo.ejb.cbm.entity.KK1681ETMsg;
import eo.ejb.cbm.entity.KK1681LE;
import eo.ejb.cbm.entity.ZM0411ETMsg;
import eo.ejb.cbm.entity.ZM0411LE;
import eo.ejb.cbm.entity.ZM0421ETMsg;
import eo.ejb.cbm.entity.ZM0421LE;
import eo.ejb.cbm.entity.ZM0431ETMsg;
import eo.ejb.cbm.entity.ZM0431LE;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0341DBABase;
import eo.ejb.common.db.JKKejbKK0801DBABase;
import eo.ejb.common.db.JKKejbKK2811DBABase;

/**
 * <p>
 * 機器提供サービス契約の関連制約部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbKK0341KRCK extends JKKejbKK0341DBABase
{
	/** 無効フラグ（有効） */
	private static final String MK_FLG_YUKO = "0";

	/** 異動予約詳細コード（コース変更） */
	private static final String IDO_RSV_DTL_CD_003 = "003";

	/** 異動予約状態コード（予約手続中） */
	private static final String IDO_RSV_STAT_CD_03 = "03";


	/**
	 * <p>
	 * 新しいJSYejbKK0341KRCKを作成します。
	 * </p>
	 */
	public JKKejbKK0341KRCK()
	{
		super();
	}

	/**
	 * <p>
	 * 機器提供サービス契約の存在チェックを行います。（世代登録年月日時分秒を除く有効なレコード）
	 * </p>
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @return レコードが存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isExistsNonGene(String kktkSvcKeiNo)
	{
		if (kktkSvcKeiNo == null || "".equals(kktkSvcKeiNo))
		{
			return true;
		}

		// ETメッセージ
		CAANMsg msg = new CAANMsg(KK0341ETMsg.class.getName());
		msg.set(KK0341ETMsg.KKTK_SVC_KEI_NO, kktkSvcKeiNo);
		msg.set(KK0341ETMsg.MK_FLG, "0");

		// ロジカルエンティティ生成
		KK0341LE le = new KK0341LE();

		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 inContext Agentから渡されたAgentDispatchContext
	 * @return 予約レコードが存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isCheckKikiNum(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 親契約識別コードが「サービス契約」、「サービス契約内訳」の場合
		if (JKKModelConst.OYA_KEI_SKBT_CD_SVC_KEI.equals(inMsg.getString(KK0341ETMsg.OYA_KEI_SKBT_CD))
				|| JKKModelConst.OYA_KEI_SKBT_CD_SVC_KEI_UCWK.equals(inMsg.getString(KK0341ETMsg.OYA_KEI_SKBT_CD)))
		{
			// 該当の「サービス契約」カレントレコードを取得する。
			String svcKeiNo = inMsg.getString(KK0341ETMsg.SVC_KEI_NO);
			CAANMsg kk0081Msg = new JKKejbKK0081DBABase().getKK0081Current(svcKeiNo, JKKModelCommon.getOpeDate(inMsg));

			// 該当の「サービス契約」に紐づく「機器提供サービス契約」の件数を取得する。
			int keiCnt = getSvcKeiNoCntForKK0341(inMsg, svcKeiNo);

			// 機器提供サービス契約の上限数チェック
			return isKikiNumUpplChk(inMsg, kk0081Msg, keiCnt);
		}

		return true;
	}

	/**
	 * <p>
	 * 機器提供サービス契約の台数チェック(サービス契約回線内訳)を行います。
	 * </p>
	 * @param  inMsg 処理対象のメッセージキャリア
	 * @param  inContext Agentから渡されたAgentDispatchContext
	 * @return サービス契約回線内訳に紐付く機器提供サービスの件数が
	 *          最大機器提供サービス数未満の場合はtrue。以上の場合はfalse。
	 */
	public boolean isCheckKikiNumSvcKaiUk(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 親契約識別コードが「サービス契約回線内訳」の場合
		if (JKKModelConst.OYA_KEI_SKBT_CD_SVC_KEI_KAISEN_UCWK.equals(inMsg.getString(KK0341ETMsg.OYA_KEI_SKBT_CD)))
		{
			JKKejbKK0081DBABase kk0081dba = new JKKejbKK0081DBABase();
			String opeDate = JKKModelCommon.getOpeDate(inMsg);

			// 該当の「サービス契約回線内訳」を使用する「サービス契約」を取得する。
			// ※異動区分が"住所変更・登録"の場合、転居先で使用する「サービス契約」も含めて取得する。
			String svcKeiKaisenUcwkNo = inMsg.getString(KK0341ETMsg.SVC_KEI_KAISEN_UCWK_NO);
			CAANMsg[] kk0081MsgList = null;

			if(JKKModelConst.IDO_DIV_KIKI_KEI_CHG.equals(inMsg.getString(KK0341ETMsg.IDO_DIV))) 
			{
				CAANMsg[] kk0081MsgList1 = null;
				CAANMsg[] kk0081MsgList2 = null;
				
				kk0081MsgList1 = kk0081dba.getKK0081bySvcKeiKaisenUcwk(svcKeiKaisenUcwkNo, null, opeDate, "1");
				kk0081MsgList2 = kk0081dba.getKK0081bySvcKeiKaisenUcwk(svcKeiKaisenUcwkNo, null, opeDate, "3");

				// 通常異動側のサービス契約の場合、通常異動側のデータを対象とする。
				if(kk0081MsgList1 != null && kk0081MsgList1.length > 0) {
					kk0081MsgList = kk0081MsgList1;
				}
				
				// 住所変更後のサービス契約の場合、住所変更側のデータを対象とする。
				if(kk0081MsgList2 != null && kk0081MsgList2.length > 0) {
					kk0081MsgList = kk0081MsgList2;
				}
				
				if(kk0081MsgList == null) {
					return false;
				}
			}
			else if (!JKKModelConst.IDO_DIV_ADCHG_ADD.equals(inMsg.getString(KK0341ETMsg.IDO_DIV)))
			{
				kk0081MsgList = kk0081dba.getKK0081bySvcKeiKaisenUcwk(svcKeiKaisenUcwkNo, null, opeDate, "1");
			}
			else
			{
				kk0081MsgList = kk0081dba.getKK0081bySvcKeiKaisenUcwk(svcKeiKaisenUcwkNo, null, opeDate, "3");
			}
			
			// 解約済、キャンセル済を除外する
			kk0081MsgList = kk0081dba.getKK0081OutDsLCl(kk0081MsgList);

			// 該当の「サービス契約回線内訳」に紐づく「機器提供サービス契約」の件数を取得する。
			int keiCnt = getSvcKeiKaiUcwkNoCntForKK0341(inMsg, svcKeiKaisenUcwkNo);

			for (CAANMsg kk0081Msg : kk0081MsgList)
			{
				// 機器提供サービス契約の上限数チェック
				if (isKikiNumUpplChk(inMsg, kk0081Msg, keiCnt))
				{
					// 複数の「サービス契約」のうち、１件でも上限数を越えなければチェックＯＫ
					return true;
				}
			}

			// 全ての「サービス契約」について、上限数を越えればチェックＮＧ
			return false;
		}

		return true;
	}

	/**
	 * <p>
	 * 機器提供サービス契約の上限数チェックを行います。
	 * </p>
	 * @param  inMsg 処理対象のメッセージキャリア
	 * @param  kk0081Msg 処理対象の「サービス契約」メッセージキャリア
	 * @param  keiCnt 機器提供サービス契約の件数
	 * @return 機器提供サービス契約の件数が最大機器提供サービス数未満の場合はtrue。以上の場合はfalse。
	 */
	private boolean isKikiNumUpplChk(CAANMsg inMsg, CAANMsg kk0081Msg, int keiCnt)
	{
		// サービス契約.料金コースコード
		String pcrsCd = kk0081Msg.getString(KK0081ETMsg.PCRS_CD);

		// 該当の「サービス契約」に紐づく「異動予約」の新料金コースコードを取得する。
		String newPcrsCd = getNewPcrsCdKK1681(kk0081Msg.getString(KK0081ETMsg.SVC_KEI_NO));
		if (newPcrsCd != null && !"".equals(newPcrsCd))
		{
			// コース変更中で新料金コースコードが存在する場合
			pcrsCd = newPcrsCd;
		}

		// 入力.機器提供サービスコード、サービス契約.料金コースコードに紐づく「料金コース_機器提供サービス」を取得する。
		CAANMsg kk0801Msg = getKK0801Crrent(inMsg, pcrsCd);
		if (kk0801Msg == null)
		{
			// 該当の機器に対応しない「サービス契約」の場合、エラー扱い
			return false;
		}

		// 新規契約時最大機器提供サービス数、最大機器提供サービス数の取得
		int nwkejCnt = Integer.parseInt(kk0801Msg.getString(KK0801ETMsg.NWKEJ_MAX_KKTK_SVC_CNT));
		int maxCnt = Integer.parseInt(kk0801Msg.getString(KK0801ETMsg.MAX_KKTK_SVC_CNT));

		// サービス契約ステータスが"受付済"、"照査済"、"締結済"の場合
		String svcKeiStat = kk0081Msg.getString(KK0081ETMsg.SVC_KEI_STAT);
		if (JKKModelConst.SVC_KEI_STAT_UK_ZM.equals(svcKeiStat)
				|| JKKModelConst.SVC_KEI_STAT_SHOSA_ZM.equals(svcKeiStat)
				|| JKKModelConst.SVC_KEI_STAT_CNC_ZM.equals(svcKeiStat))
		{
			// 新規契約時最大機器提供サービス数と比較
			if (keiCnt >= nwkejCnt)
			{
				// 現在の契約数が新規契約時最大機器提供サービス数以上の場合エラー
				return false;
			}
		}
		else
		{
			// 最大機器提供サービス数と比較
			if (keiCnt >= maxCnt)
			{
				// 現在の契約数が最大機器サービス数以上の場合エラー
				return false;
			}
		}

		return true;
	}

	/**
	 * <p>
	 * IPv6ルーター機器チェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return サービス契約番号に紐付く機器提供サービス契約の宅内機器型式に"1"（）が存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isIPv6RouteKikiChk(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 関連制約共通処理部品インスタンス
		JKKejbKRCKCommon krck = new JKKejbKRCKCommon();
		
		// サービス契約番号を取得する
		String svcKeiNo = krck.getOyaSvcKeiNo(inMsg);

		// サービス契約番号に紐づく機器提供サービス契約を取得
		CAANMsg[] retMsgKK0341List = krck.findByKK0341WithSvc(inMsg, inContext, svcKeiNo);
		
		// 解約済、キャンセル済を除外する
		JKKejbKK0341DBABase kk0341dba = new JKKejbKK0341DBABase();
		retMsgKK0341List = kk0341dba.getKK0341OutDsLCl(retMsgKK0341List);

		for (CAANMsg retMsgKK0341: retMsgKK0341List)
		{
			
			// 多機能ルータの場合
			if (JKKModelConst.KKTK_SVC_CD_TAKINORT.equals(retMsgKK0341.getString(KK0341ETMsg.KKTK_SVC_CD)))
			{

				// 宅内機器種別コードに紐付く、宅内機器型式を取得
				CAANMsg[] retMsgZM0411List = findByZM0411TakunkikiSbt(retMsgKK0341.getString(KK0341ETMsg.TAKNKIKI_SBT_CD));
				
				for (CAANMsg retMsgZM0411: retMsgZM0411List)
				{
					// 「IPv6対応フラグ」が"1"の場合はtrueを返却する
					if ("1".equals(retMsgZM0411.getString(ZM0411ETMsg.IPV6_TAIO_FLG)))
					{
						return true;
					}
				}
			}
			else
			{
				// 宅内機器型式コードに紐付く、宅内機器型式を取得
				CAANMsg retMsgZM0411 = findByZM0411Valid(retMsgKK0341.getString(KK0341ETMsg.TAKNKIKI_MODEL_CD));

				// 宅内機器型式が存在しない場合は次の明細へ
				if (null == retMsgZM0411)
				{
					continue;
				}

				// 「IPv6対応フラグ」が"1"の場合はtrueを返却する
				if ("1".equals(retMsgZM0411.getString(ZM0411ETMsg.IPV6_TAIO_FLG)))
				{
					return true;
				}
			}
		}

		// それ以外の場合はfalseを返却する
		return false;
	}
	
	/**
	 * <p>
	 * IPv6ルーター機器出荷済チェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号
	 * @return サービス契約番号に紐付くIPv6ルーターの機器提供サービス契約の機器製造番号が設定されている場合はtrue
	 *          未設定の場合はfalse。
	 */
	public boolean isIPv6RouteKikiSyukaChk(CAANMsg inMsg, AgentDispatchContext inContext, String svcKeiNo)
	{
		// 関連制約共通処理部品インスタンス
		JKKejbKRCKCommon krck = new JKKejbKRCKCommon();

		// サービス契約番号に紐づく機器提供サービス契約を取得
		CAANMsg[] retMsgKK0341List = krck.findByKK0341WithSvc(inMsg, inContext, svcKeiNo);
		
		long ipv6kikisyukacnt = 0L;

		for (CAANMsg retMsgKK0341: retMsgKK0341List)
		{
			// 宅内機器型式コードに紐付く、宅内機器型式を取得
			CAANMsg retMsgZM0411 = findByZM0411Valid(retMsgKK0341.getString(KK0341ETMsg.TAKNKIKI_MODEL_CD));

			// 宅内機器型式が存在しない場合は次の明細へ
			if (null == retMsgZM0411)
			{
				continue;
			}

			// 「IPv6対応フラグ」が"1"以外の場合は次の明細へ
			if (!"1".equals(retMsgZM0411.getString(ZM0411ETMsg.IPV6_TAIO_FLG)))
			{
				continue;
			}
						
			// 機器製造番号が設定されている場合出荷機器数に＋１
			if (!JKKModelConst.SVC_KEI_STAT_DSL_ZM.equals(retMsgKK0341.getString(KK0341ETMsg.KKTK_SVC_KEI_STAT)) 
					&&  !JKKModelConst.SVC_KEI_STAT_CNCL_ZM.equals(retMsgKK0341.getString(KK0341ETMsg.KKTK_SVC_KEI_STAT)) 
					&&!retMsgKK0341.isNull(KK0341ETMsg.KIKI_SEIZO_NO))
			{
				ipv6kikisyukacnt++;
			}
		}
		
		// IPv6ルーター機器が0またはIPv6ルーター機器が全て出荷されていない場合falseを返却
		if (1 > ipv6kikisyukacnt)
		{
			return false;
		}
		
		// それ以外の場合はtrueを返却する
		return true;
	}

	/**
	 * <p>
	 * 料金コース＿機器提供サービスのカレント検索を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param pcrsCd 料金コースコード
	 * @return 検索結果
	 */
	private CAANMsg getKK0801Crrent(CAANMsg inMsg, String pcrsCd)
	{
		// ETメッセージ
		CAANMsg msg = new CAANMsg(KK0801ETMsg.class.getName());
		msg.set(KK0801ETMsg.KKTK_SVC_CD, inMsg.getString(KK0341ETMsg.KKTK_SVC_CD));
		msg.set(KK0801ETMsg.PCRS_CD, pcrsCd);
		msg.set(KK0801ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		return new JKKejbKK0801DBABase().findByCurrent(msg);
	}

	/**
	 * <p>
	 * サービス契約番号に紐付く機器提供サービス契約のカレント数を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo サービス契約番号
	 * @return カレントレコードの数
	 */
	private int getSvcKeiNoCntForKK0341(CAANMsg inMsg, String svcKeiNo)
	{
		JKKejbKK0341DBABase kk0341dba = new JKKejbKK0341DBABase();
		String opeDate = JKKModelCommon.getOpeDate(inMsg);

		// 追加検索条件：機器提供サービス契約.機器提供サービスコード = 入力.機器提供サービスコード
		HashMap<String, String[]> searchJknMap = new HashMap<String, String[]>();
		searchJknMap.put(KK0341ETMsg.KKTK_SVC_CD, new String[] {inMsg.getString(KK0341ETMsg.KKTK_SVC_CD)});
		
		// 該当の「サービス契約」に紐づく「機器提供サービス契約」を取得する。
		CAANMsg[] kk0341MsgList = kk0341dba.getKK0341bySvcKei(svcKeiNo, searchJknMap, opeDate, "4");
		
		// 解約済、キャンセル済を除外する
		kk0341MsgList = kk0341dba.getKK0341OutDsLCl(kk0341MsgList);

		return kk0341MsgList.length;
	}
	
	/**
	 * <p>
	 * サービス契約回線内訳番号に紐付く機器提供サービス契約のカレント数を取得します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param svcKeiKaisenUcwkNo サービス契約回線内訳番号
	 * @return カレントレコードの数
	 */
	private int getSvcKeiKaiUcwkNoCntForKK0341(CAANMsg inMsg, String svcKeiKaisenUcwkNo)
	{
		JKKejbKK0341DBABase kk0341dba = new JKKejbKK0341DBABase();
		String opeDate = JKKModelCommon.getOpeDate(inMsg);

		// 追加検索条件：機器提供サービス契約.機器提供サービスコード = 入力.機器提供サービスコード
		HashMap<String, String[]> searchJknMap = new HashMap<String, String[]>();
		searchJknMap.put(KK0341ETMsg.KKTK_SVC_CD, new String[] {inMsg.getString(KK0341ETMsg.KKTK_SVC_CD)});
		
		// 該当の「サービス契約回線内訳」に紐づく「機器提供サービス契約」を取得する。
		CAANMsg[] kk0341MsgList = kk0341dba.getKK0341bySvcKeiKaisenUcwk(svcKeiKaisenUcwkNo, searchJknMap, opeDate);
		
		// 解約済、キャンセル済を除外する
		kk0341MsgList = kk0341dba.getKK0341OutDsLCl(kk0341MsgList);

		return kk0341MsgList.length;
	}

	/**
	 * <p>
	 * サービス契約番号に紐付く新料金コースコードを取得します。
	 * </p>
	 * @param svcKeiNo サービス契約番号
	 * @return 新料金コースコード
	 */
	private String getNewPcrsCdKK1681(String svcKeiNo)
	{
		// ETメッセージ
		CAANMsg msg = new CAANMsg(KK1681ETMsg.class.getName());
		msg.set(KK1681ETMsg.SVC_KEI_NO, svcKeiNo);
		msg.set(KK1681ETMsg.IDO_RSV_DTL_CD, IDO_RSV_DTL_CD_003);
		msg.set(KK1681ETMsg.IDO_RSV_STAT_CD, IDO_RSV_STAT_CD_03);
		msg.set(KK1681ETMsg.MK_FLG, MK_FLG_YUKO);

		CAANMsg[] otETMsg = null;
		try
		{
			otETMsg = new KK1681LE().findByCondition(msg);
		}
		catch (CAANException e1)
		{
			throw new CAANRuntimeException(e1);
		}

		//検索結果が0件の場合NULLを返す
		if (1 > otETMsg.length)
		{
			return null;
		}

		return otETMsg[0].getString(KK1681ETMsg.NEW_PCRS_CD);
	}

	/**
	 * <p>
	 * 宅内機器型式コードに紐づく、有効な宅内機器型式レコードを取得する。
	 * </p>
	 * @param taknkikiModelCd 宅内機器型式コード
	 * @return 宅内機器型式コードに紐づく有効な宅内機器のレコード
	 */
	private CAANMsg findByZM0411Valid(String taknkikiModelCd)
	{
		// 一意検索用メッセージ
		CAANMsg inMsgZM0411 = new CAANMsg(ZM0411ETMsg.class.getName());
		inMsgZM0411.set(ZM0411ETMsg.TAKNKIKI_MODEL_CD, taknkikiModelCd);

		// 一意検索
		CAANMsg retMsgZM0411 = new ZM0411LE().findByPrimaryKey(inMsgZM0411);

		// データが取得できなかった場合はnullを返却
		if (null == retMsgZM0411)
		{
			return null;
		}

		// 取得結果が有効でない場合はnullを返却
		if (!MK_FLG_YUKO.equals(retMsgZM0411.getString(ZM0411ETMsg.MK_FLG)))
		{
			return null;
		}

		return retMsgZM0411;
	}

	/**
	 * <p>
	 * 機器提供サービス契約スキーマの機器提供サービス契約番号に紐付く機器提供サービスコードが"C004"または"C024"のカレントレコードを取得する。
	 * 取得したレコードに紐付く返品機器スキーマの返品機器ステータスが"002","003"の場合、チェックNG としてfalseを返却する。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param svcKeiKaisenUcwkNo サービス契約回線内訳番号
	 * @return サービス契約番号
	 */
	public boolean isCheckHmpinKikiStat(CAANMsg inMsg, AgentDispatchContext inContext, Object kktkSvcKeiNo) {

		// コネクション
		Connection con = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// SQL文
		StringBuffer sbSql = new StringBuffer();

		try
		{
			// 対象テーブルのコネクション取得
			con = JSYejbConnection.getConnection(KK0241ETMsg.getTableName());
			
			sbSql.append("  SELECT ")
				.append("       COUNT(*) AS CNT ")
				.append("  FROM ")
				.append("       KK_T_KKTK_SVC_KEI KK0341 ")
				.append("  INNER JOIN ")
				.append("       DK_T_HMPIN_KIKI DK0301 ")
				.append("  ON ")
				.append("       DK0301.KKTK_SVC_KEI_NO = KK0341.KKTK_SVC_KEI_NO ")
				.append("  AND ")
				.append("       DK0301.KIKI_CHG_NO = KK0341.KIKI_CHG_NO ")
				.append(" WHERE ")
				.append("       KK0341.KKTK_SVC_KEI_NO = ? ")
				.append("   AND ")
				// ANK-4315-00-00 ADD START
//				.append("       KK0341.KKTK_SVC_CD IN('C004', 'C024') ")
				.append("       KK0341.KKTK_SVC_CD IN('C004', 'C024', 'C025') ")
				// ANK-4315-00-00 ADD END
				.append("   AND ")
				.append("       (KK0341.KKTK_SVC_KEI_NO, KK0341.GENE_ADD_DTM) = ")
				.append("          (SELECT KK0341_GENE.KKTK_SVC_KEI_NO, MAX(KK0341_GENE.GENE_ADD_DTM) AS KK0341_MAX ")
				.append("           FROM   KK_T_KKTK_SVC_KEI KK0341_GENE ")
				.append("           WHERE  KK0341_GENE.KKTK_SVC_KEI_NO = KK0341.KKTK_SVC_KEI_NO ")
				.append("           AND    KK0341_GENE.RSV_APLY_CD = '2' ")
				.append("           AND    KK0341_GENE.MK_FLG = '0' ")
				.append("           GROUP BY KK0341_GENE.KKTK_SVC_KEI_NO) ")
				.append("   AND ")
				.append("       DK0301.HMPIN_KIKI_STAT IN ('002', '003')  ")
				.append("   AND ")
				.append("       DK0301.MK_FLG = '0' ");
			

			// repareStatementにSQL文をセット
			pstmt = con.prepareStatement(sbSql.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sbSql);
			
			// パラメータの設定(サービス契約回線内訳番号)
			CAANJDBCUtil.setParam(pstmt, 1, kktkSvcKeiNo);
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			if (rsltQuery.next())
			{
				if(rsltQuery.getInt("CNT") > 0)
				{
					return false;
				}
				// 取得結果が0件の場合、チェックOK
				return true;
			}
			return false;
			
			
		} catch(SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if(rsltQuery != null)
				{
					rsltQuery.close();
				}
				if(pstmt != null)
				{
					pstmt.close();
				}
				if(con != null)
				{
					CAANConnectionMgr.getInstance().close(con);
				}
			}
			catch(SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
	}

	/**
	 * <p>
	 * 機器送付先住所変更チェックを行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @param kikiSohusAdCd 機器送付先住所コード
	 * @param kikiSohusPcd 機器送付先郵便番号
	 * @return 機器送付先住所が変更されている場合はtrue。変更されていない場合はfalse。
	 */
	public boolean isKikiSohusAdChg(CAANMsg inMsg, AgentDispatchContext inContext, String kktkSvcKeiNo, String kikiSohusAdCd, String kikiSohusPcd)
	{
		// 機器送付先住所コードが未設定の場合
		if (kikiSohusAdCd == null || "".equals(kikiSohusAdCd))
		{
			return false;
		}
		// 機器送付先郵便番号が未設定の場合
		if (kikiSohusPcd == null || "".equals(kikiSohusPcd))
		{
			return false;
		}

		// カレント検索用のメッセージを作成
		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 currentKK0341 = new JKKejbKK0341DBABase().findByCurrent(inETMsg);
		if (currentKK0341 == null)
		{
			return false;
		}

		// カレントレコードの機器送付先住所と同一の場合
		if(kikiSohusAdCd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_SOHUS_AD_CD)) && 
				kikiSohusPcd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_SOHUS_PCD)))
		{
			return false;
		}

		return true;
	}

	/**
	 * <p>
	 * IPv6ルーター機器チェック（機器オプション）を行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return サービス契約番号に紐付く機器提供サービス契約の宅内機器型式に"1"（）が存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isIPv6RouteKikiOpChk(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		boolean retcode = true;
		
		// 関連制約共通処理部品インスタンス
		JKKejbKRCKCommon krck = new JKKejbKRCKCommon();
		
		// サービス契約番号を取得する
		String svcKeiNo = krck.getOyaSvcKeiNo(inMsg);

		// サービス契約番号に紐づく機器提供サービス契約を取得
		CAANMsg[] retMsgKK0341List = krck.findByKK0341WithSvc(inMsg, inContext, svcKeiNo);
		
		// 解約済、キャンセル済を除外する
		JKKejbKK0341DBABase kk0341dba = new JKKejbKK0341DBABase();
		retMsgKK0341List = kk0341dba.getKK0341OutDsLCl(retMsgKK0341List);

		for (CAANMsg retMsgKK0341: retMsgKK0341List)
		{
			String kktkSvcKeiNo = retMsgKK0341.getString(KK0341ETMsg.KKTK_SVC_KEI_NO);			
			String kktkSvcKeiCD = retMsgKK0341.getString(KK0341ETMsg.KKTK_SVC_CD);
			
			// 有効な多機能ルータが１件でも存在する場合は基本falseを選択する。
			if(JKKModelConst.KKTK_SVC_CD_TAKINORT.equals(kktkSvcKeiCD)) {
				retcode = false;
				
				// 多機能ルータに紐づく機器オプションサービス契約が存在しない場合にエラーとする。
				CAANMsg[] kk2811Msg = new JKKejbKK2811DBABase().getKK2811byKktk(kktkSvcKeiNo, null , JKKModelCommon.getOpeDate(inMsg) ,"2");
				
				for(CAANMsg kk2811ETMsg : kk2811Msg) {
					
					
					if(kk2811Msg == null || kk2811Msg.length == 0) {
						retcode = false;
					}
					// 多機能ルータのルータ機能が１件でも有効な場合、即座にtrueを返却する。
					else {
						return true;
					}
				}				
			}
		}

		// それ以外の場合はfalseを返却する
		return retcode;
	}
	
	/**
	 * <p>
	 * 宅内機器種別コードに紐づく、有効な宅内機器型式レコードを取得する。
	 * </p>
	 * @param taknkikiSbtCd 宅内機器種別コード
	 * @return 宅内機器型式コードに紐づく有効な宅内機器のリスト
	 */
	private CAANMsg[] findByZM0411TakunkikiSbt(String taknkikiSbtCd)
	{
		CAANMsg inMsgZM0411 = new CAANMsg(ZM0411ETMsg.class.getName());
		inMsgZM0411.set(ZM0411ETMsg.TAKNKIKI_SBT_CD, taknkikiSbtCd);
		inMsgZM0411.set(ZM0411ETMsg.MK_FLG, MK_FLG_YUKO);
		CAANMsg[] retMsgZM0411;
		
		try
		{
			retMsgZM0411 = new ZM0411LE().findByCondition(inMsgZM0411);
		}
		catch (CAANException ex)
		{
			throw new CAANRuntimeException(ex);
		}

		return retMsgZM0411;
	}
	
	/**
	 * <p>
	 * 工事会社棚マスタ存在チェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @param geneAddDtm 世代登録年月日時分秒
	 * @param kikiStiJiKocompCd 機器指定時工事会社コード
	 * @param kikiStiJiKocompSlfCd 機器指定時工事会社棚コード
	 * @return 工事会社棚マスタにデータが存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isKikiStiCompChk(CAANMsg inMsg, AgentDispatchContext inContext, String kktkSvcKeiNo, String geneAddDtm, String kikiStiJiKocompCd, String kikiStiJiKocompSlfCd)
	{
			
		// 機器指定時工事会社コードが未設定の場合、trueを返却
		if (kikiStiJiKocompCd == null || "".equals(kikiStiJiKocompCd))
		{
			return true;
		}
		// 機器指定時工事会社棚コードが未設定の場合、trueを返却
		if (kikiStiJiKocompSlfCd == null || "".equals(kikiStiJiKocompSlfCd))
		{
			return true;
		}
				
		// 機器提供サービス契約のカレント検索を行う
		CAANMsg currentKK0341 = findByKK0341(inMsg, kktkSvcKeiNo, geneAddDtm);
		// データが存在しない場合、trueを返却
		if (currentKK0341 == null)
		{
			return true;
		}
		
		// 機器指定時工事会社コード、機器指定時工事会社棚コードがカレントレコードと異なる場合
		if (!kikiStiJiKocompCd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_STI_JI_KOCOMP_CD)) || 
				!kikiStiJiKocompSlfCd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_STI_JI_KOCOMP_SLF_CD)))
		{
			// 工事会社棚マスタの検索結果が存在しない場合、falseを返却
			CAANMsg[] resultMsg = findByZM0421(kikiStiJiKocompCd, kikiStiJiKocompSlfCd);
			if (resultMsg == null || resultMsg.length == 0)
			{
				return false;
			}
		}

		return true;
	}
	
	/**
	 * <p>
	 * 預託先オフィス棚マスタ存在チェックを行う。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @param geneAddDtm 世代登録年月日時分秒
	 * @param kikiStiJiYtkskofCd 機器指定時預託先オフィスコード
	 * @param kikiStiJiYtkskofSlfCd 機器指定時預託先オフィス棚コード
	 * @return 預託先オフィス棚マスタにデータが存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean isKikiStiYtkskofChk(CAANMsg inMsg, AgentDispatchContext inContext, String kktkSvcKeiNo, String geneAddDtm, String kikiStiJiYtkskofCd, String kikiStiJiYtkskofSlfCd)
	{

		// 機器指定時預託先オフィスコードが未設定の場合、trueを返却
		if (kikiStiJiYtkskofCd == null || "".equals(kikiStiJiYtkskofCd))
		{
			return true;
		}
		// 機器指定時預託先オフィス棚コードが未設定の場合、trueを返却
		if (kikiStiJiYtkskofSlfCd == null || "".equals(kikiStiJiYtkskofSlfCd))
		{
			return true;
		}
		
		// 機器提供サービス契約のカレント検索を行う
		CAANMsg currentKK0341 = findByKK0341(inMsg, kktkSvcKeiNo, geneAddDtm);
		// データが存在しない場合、trueを返却
		if (currentKK0341 == null)
		{
			return true;
		}
		
		// 機器指定時工事会社コード、機器指定時工事会社棚コードがカレントレコードと異なる場合
		if (!kikiStiJiYtkskofCd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_STI_JI_YTKSKOF_CD)) || 
				!kikiStiJiYtkskofSlfCd.equals(currentKK0341.getString(KK0341ETMsg.KIKI_STI_JI_YTKSKOF_SLF_CD)))
		{
			// 預託先オフィス棚マスタの検索結果が存在しない場合、falseを返却
			CAANMsg[] resultMsg = findByZM0431(kikiStiJiYtkskofCd, kikiStiJiYtkskofSlfCd);
			if (resultMsg == null || resultMsg.length == 0)
			{
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * <p>
	 * 機器提供サービス契約番号に紐づく、有効な機器提供サービス契約レコードを取得する。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param kktkSvcKeiNo 機器提供サービス契約番号
	 * @param geneAddDtm 世代登録年月日時分秒
	 * @return 機器提供サービス契約のカレントレコード
	 */
	private CAANMsg findByKK0341(CAANMsg inMsg, String kktkSvcKeiNo, String geneAddDtm)
	{
		CAANMsg currentKK0341 = null;
		
		CAANMsg inETMsg = new CAANMsg(KK0341ETMsg.class.getName());
		inETMsg.set(KK0341ETMsg.KKTK_SVC_KEI_NO, kktkSvcKeiNo);
		inETMsg.set(KK0341ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));
		
		String templateID = inMsg.getString(JCMConstants.TEMPLATE_ID_KEY);
		
		// 機器提供サービス契約情報変更（契約変更中）から呼び出された場合
		if ("EKK0341C231".equals(templateID))
		{
			inETMsg.set(KK0341ETMsg.GENE_ADD_DTM, geneAddDtm);
			
			// 機器提供サービス契約のプライマリーキー検索を行う
			currentKK0341 = new JKKejbKK0341DBABase().findByPrimaryKey(inETMsg);
		}
		else
		{
			// 機器提供サービス契約のカレント検索を行う
			currentKK0341 = new JKKejbKK0341DBABase().findByCurrent(inETMsg);			
		}

		return currentKK0341;
	}

	/**
	 * <p>
	 * 機器指定時工事会社コード、機器指定時工事会社棚コードに紐づく、有効な工事会社棚レコードを取得する。
	 * </p>
	 * @param KojicompCd 機器指定時工事会社コード
	 * @param KojicomSlfpCd 機器指定時工事会社棚コード
	 * @return 工事会社棚レコードのリスト
	 */
	private CAANMsg[] findByZM0421(String KojicompCd, String KojicomSlfpCd)
	{
		CAANMsg inMsgZM0421 = new CAANMsg(ZM0421ETMsg.class.getName());
		inMsgZM0421.set(ZM0421ETMsg.KOJI_COMP_CD, KojicompCd);
		inMsgZM0421.set(ZM0421ETMsg.KOJI_COMP_SLF_CD, KojicomSlfpCd);
		inMsgZM0421.set(ZM0421ETMsg.MK_FLG, MK_FLG_YUKO);
		CAANMsg[] retMsgZM0421;
		
		try
		{
			retMsgZM0421 = new ZM0421LE().findByCondition(inMsgZM0421);
		}
		catch (CAANException ex)
		{
			throw new CAANRuntimeException(ex);
		}

		return retMsgZM0421;
	}
	
	/**
	 * <p>
	 * 機器指定時預託先オフィスコード、機器指定時預託先オフィス棚コードに紐づく、有効な預託先オフィス棚レコードを取得する。
	 * </p>
	 * @param yotakuSakioffcCd 機器指定時預託先オフィスコード
	 * @param yotakuSakioffSlfCd 機器指定時預託先オフィス棚コード
	 * @return 預託先オフィス棚レコードのリスト
	 */
	private CAANMsg[] findByZM0431(String yotakuSakioffcCd, String yotakuSakioffSlfCd)
	{
		CAANMsg inMsgZM0431 = new CAANMsg(ZM0431ETMsg.class.getName());
		inMsgZM0431.set(ZM0431ETMsg.YOTAKU_SAKI_OFFC_CD, yotakuSakioffcCd);
		inMsgZM0431.set(ZM0431ETMsg.YOTAKU_SAKI_OFFC_SLF_CD, yotakuSakioffSlfCd);
		inMsgZM0431.set(ZM0431ETMsg.MK_FLG, MK_FLG_YUKO);
		CAANMsg[] retMsgZM0431;
		
		try
		{
			retMsgZM0431 = new ZM0431LE().findByCondition(inMsgZM0431);
		}
		catch (CAANException ex)
		{
			throw new CAANRuntimeException(ex);
		}

		return retMsgZM0431;
	}

}
