/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKejbSetMskmChkBase
*   ソースファイル名：JKKejbSetMskmChkBase.java
*   作成者          ：富士通
*   日付            ：2011年11月01日
*＜機能概要＞
*   セット申込チェック部品スーパークラス
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/11/01  富士通      新規作成
*　 v6.00.00	2014/01/14	FJ)寺園	 	OM-2013-0005388
*
**********************************************************************/
package eo.ejb.common.db;

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 eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK1071ETMsg;
import eo.ejb.cbm.entity.KK1071LE;
import eo.ejb.common.JKKModelCommon;

/**
 * <p>
 * セット申込チェック部品のスーパークラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbSetMskmChkBase extends JKKejbShosaChkBase
{
		
	/** サービス契約番号 */
	private static final String SVC_KEI_NO = "SVC_KEI_NO";
		
	/** 審査判定結果コード */
	private static final String JUDGE_RSLT_CD_NG = "01";
	
	/** 状態遷移定義（キャンセル）* */
	private static final String STATE_CANCEL = "920";
	
	/** チェック結果（OK）**/
	private static final String RETURN_OK = "0";

	/** チェック結果（NG）**/
	private static final String RETURN_NG = "1";
	
	/** 照査対象コード(セット申込チェック) **/
	protected static final String SHOSACHK_TRG_037 = "037";
	
	
	/**
	 * <p>
	 * セット申込のチェックを行う。
	 * </p>
	 * @param inMsg 処理対象メッセージキャリア
	 * @param svcKeiNo サービス契約番号
	 * @param kidoCd 起動元コード
	 * @return チェック結果(OK:0, NG:1)
	 */
	protected String chkSetMskm(CAANMsg inMsg, String svcKeiNo, String kidoCd)
	{

		// サービス契約のカレント検索
		CAANMsg msg0081 = this.getSvckei(inMsg, svcKeiNo, kidoCd);
		
		// 存在しない場合
		if (msg0081 == null)
		{
			// OKを設定して処理終了
			return RETURN_OK;
		}
		
		// 申込明細のカレント検索
		CAANMsg msg0021 = getMskmDtl(inMsg, msg0081, kidoCd); 
		
		// 存在しない場合
		if (msg0021 == null)
		{
			// OKを設定して処理終了
			return RETURN_OK;
		}
		
		// キャンセル済みは対象外
		if (STATE_CANCEL.equals(msg0021.getString(KK0021ETMsg.MSKM_DTL_STAT)))
		{
			// OKを設定して処理終了
			return RETURN_OK;
		}
		
		// セット申込チェック@（自動照査対象サービスチェック）
		if (!chkSetMskm1(msg0081, msg0021, getOpeDate(inMsg, kidoCd)))
		{
			// NGを設定して処理終了
			return RETURN_NG;
		}
		
		// セット申込チェックA（自動照査処理状態チェック）
		// セット申込情報取得処理を呼び出す
		ArrayList<HashMap<String, String>> list= getSetMskm(msg0081, msg0021, getOpeDate(inMsg, kidoCd));
		
		if(list == null || list.size() == 0)
		{
			// OKを設定して処理終了
			return RETURN_OK;
		}
		
		for(int i = 0; i < list.size(); i++)
		{
			// 取得できた件数分審査の検索を行う。
			// 審査の全件件数をする
			CAANMsg[] judge = getJudgeList(list.get(i), kidoCd);
			
			// 検索結果の件数をチェックする
			if(judge.length == 0)
			{
				// 次のレコードへ
				continue;
			}
			
			// 取得結果の審査結果判定コードをチェックする
			if(!isJudgeRsltCdChk(judge))
			{
				// NGを設定して処理終了
				return RETURN_NG;
			}
		}
		
		return RETURN_OK;
	}
	
	
	/**
	 * <p>
	 * 運用日付を取得する。
	 * </p>
	 * @param inMsg 処理対象メッセージキャリア
	 * @param kidoCd 起動元コード
	 * @return 運用日付
	 */
	private String getOpeDate(CAANMsg inMsg, String kidoCd)
	{
		// オンライン運用日
		if (KIDOMOTO_CODE_ONLINE.equals(kidoCd))
		{
			return JKKModelCommon.getOpeDate(inMsg);
		}
		// バッチ運用日
		else if (KIDOMOTO_CODE_BATCH.equals(kidoCd))
		{
			return JKKModelCommon.getBatOpeDate(inMsg);
		}
		else
		{
			return JKKModelCommon.getSysDate();
		}
	}
	
	/**
	 * <p>
	 * 申込明細情報を取得する。
	 * </p>
	 * @param inMsg 処理対象メッセージキャリア
	 * @param svcKeiList サービス契約情報
	 * @param kidoCd 起動元コード
	 * @return 同一の申込書番号及び申込年月日
	 */
	private CAANMsg getMskmDtl(CAANMsg inMsg, CAANMsg svcKei, String kidoCd)
	{
		CAANMsg msg0021 = new CAANMsg(KK0021ETMsg.class.getName());

		msg0021.set(KK0021ETMsg.MSKM_DTL_NO, svcKei.getString(KK0021ETMsg.MSKM_DTL_NO));
		
		// 作成したメッセージを使用して検索を行う
		CAANMsg otETMsg = new JKKejbKK0021DBABase().findByCurrent(msg0021);		
		
		return otETMsg;
	}
	
	/**
	 * <p>
	 * 審査を取得する。
	 * </p>
	 * @param inMsg 処理対象メッセージキャリア
	 * @param map サービス契約番号
	 * @param kidoCd 起動元コード
	 * @return 審査情報の取得結果
	 */
	private CAANMsg[] getJudgeList(HashMap<String, String> map, String kidoCd)
	{
		
		// 審査の全件検索
		CAANMsg msg1071 = new CAANMsg(KK1071ETMsg.class.getName());
		msg1071.set(KK1071ETMsg.SVC_KEI_NO, map.get(KK1071ETMsg.SVC_KEI_NO));
		msg1071.set(KK1071ETMsg.MK_FLG, MK_FLG_0);
	
		CAANMsg[] msgKK1071List = null;
		KK1071LE le = new KK1071LE();
		try
		{
			msgKK1071List = le.findByCondition(msg1071);

		}
		catch (CAANException e1)
		{
			throw new CAANRuntimeException(e1);
		}
		
		return msgKK1071List;
	}
	
	/**
	 * <p>
	 * 取得した審査のレコードの審査結果判定コードのチェックを行う
	 * </p>
	 * @param inMsg 審査のメッセージキャリア
	 * @return 審査結果判定コードがOK("00")の場合true、それ以外の場合falseを返却
	 */
	private boolean isJudgeRsltCdChk(CAANMsg[] inMsg)
	{
		for(int i = 0; i < inMsg.length; i++)
		{
			// 取得したレコードの審査結果判定コードがNG("01")であるか判定を行う
			if(JUDGE_RSLT_CD_NG.equals(inMsg[i].getString(KK1071ETMsg.JUDGE_JUDGE_RSLT_CD)))
			{
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * <p>
	 * セット申込を取得する。
	 * </p>
	 * @param msg0081 サービス契約のメッセージキャリア
	 * @param msg0021 申込明細のメッセージキャリア
	 * @param opeDate 運用日付
	 * @return セット申込のサービス契約番号
	 */
	private ArrayList<HashMap<String, String>> getSetMskm(CAANMsg msg0081, CAANMsg msg0021, String opeDate)
	{

		// 取得結果格納リスト
		ArrayList<HashMap<String, String>> listRslt = new ArrayList<HashMap<String, String>>();
		
		// コネクション
		Connection con = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		// SQL文
		StringBuffer sbSql = new StringBuffer();

		sbSql.append("SELECT KK0081.SVC_KEI_NO  ");
		sbSql.append("FROM   KK_T_SVC_KEI KK0081  ");
		sbSql.append("INNER JOIN KK_T_MSKM_DTL KK0021 ");
		sbSql.append("ON KK0081.MSKM_DTL_NO = KK0021.MSKM_DTL_NO ");
		sbSql.append("WHERE  KK0081.SVC_KEI_NO <> ? ");
		sbSql.append("AND    KK0081.SHOSA_YMD IS NULL ");
		sbSql.append("AND    KK0081.SVC_KEI_STAT = '010' ");
		sbSql.append("AND    KK0081.AUTO_SHOSA_TRAN_STAT_CD = '2' ");
		sbSql.append("AND   (KK0081.SVC_KEI_NO, KK0081.RSV_APLY_YMD || KK0081.GENE_ADD_DTM) =  ");
		sbSql.append("       (SELECT KK0081_GENE.SVC_KEI_NO, MAX(KK0081_GENE.RSV_APLY_YMD || KK0081_GENE.GENE_ADD_DTM) AS KK0081_MAX ");
		sbSql.append("        FROM   KK_T_SVC_KEI KK0081_GENE ");
		sbSql.append("        WHERE  KK0081_GENE.SVC_KEI_NO = KK0081.SVC_KEI_NO ");
		sbSql.append("        AND    KK0081_GENE.RSV_APLY_CD = '2' ");
		sbSql.append("        AND    KK0081_GENE.RSV_APLY_YMD <= ? ");
		sbSql.append("        AND    KK0081_GENE.MK_FLG = '0' ");
		sbSql.append("        GROUP BY KK0081_GENE.SVC_KEI_NO)");
		sbSql.append("AND KK0021.MSKM_NO = ? ");
		sbSql.append("AND KK0021.MSKM_DTL_STAT <> '920' ");
		sbSql.append("AND (KK0021.MSKM_DTL_NO, KK0021.GENE_ADD_DTM) = ");
		sbSql.append("    (SELECT KK0021_GENE.MSKM_DTL_NO, MAX(KK0021_GENE.GENE_ADD_DTM) AS KK0021_MAX ");
		sbSql.append("     FROM KK_T_MSKM_DTL KK0021_GENE ");
		sbSql.append("     WHERE KK0021_GENE.MSKM_DTL_NO = KK0021.MSKM_DTL_NO ");
		sbSql.append("     AND   KK0021_GENE.MK_FLG = '0' ");
		sbSql.append("     GROUP BY KK0021_GENE.MSKM_DTL_NO) ");

		try
		{

			//コネクション取得
			con = JSYejbConnection.getConnection(KK0081ETMsg.getTableName());

			//prepareStatementにSQL文をセット
			pstmt = con.prepareStatement(sbSql.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), sbSql);

			// バインド変数設定
			CAANJDBCUtil.setParam(pstmt, 1, msg0081.getString(KK0081ETMsg.SVC_KEI_NO));
			CAANJDBCUtil.setParam(pstmt, 2, opeDate);
			CAANJDBCUtil.setParam(pstmt, 3, msg0021.getString(KK0021ETMsg.MSKM_NO));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// 取得結果をマップに格納
			while (rsltQuery.next())
			{
				HashMap<String, String> mapRslt = new HashMap<String, String>();

				mapRslt.put(SVC_KEI_NO, rsltQuery.getString(1));
				listRslt.add(mapRslt);
			}

		}
		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);
			}
		}
		
		return listRslt;
	}
	
	/**
	 * <p>
	 * 自動照査対象サービスをチェックする。
	 * </p>
	 * @param msg0081 サービス契約のメッセージキャリア
	 * @param msg0021 申込明細のメッセージキャリア
	 * @param opeDate 運用日付
	 * @return true:チェックOK、false:チェックNG
	 */
	private boolean chkSetMskm1(CAANMsg msg0081, CAANMsg msg0021, String opeDate)
	{
		
		// コネクション
		Connection con = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		// SQL文
		StringBuffer sbSql = new StringBuffer();

		sbSql.append(" SELECT COUNT(*) AS CNT   ");
		sbSql.append(" FROM   KK_T_SVC_KEI KK0081   ");
		sbSql.append(" INNER JOIN KK_T_MSKM_DTL KK0021  ");
		sbSql.append(" ON KK0081.MSKM_DTL_NO = KK0021.MSKM_DTL_NO  ");
		sbSql.append(" WHERE  KK0021.MSKM_NO = ?  ");
		sbSql.append(" AND    KK0081.SVC_KEI_NO <> ?  ");
		sbSql.append(" AND    KK0021.MSKM_DTL_STAT <> '920'  ");
		sbSql.append(" AND   (KK0081.SVC_KEI_NO, KK0081.RSV_APLY_YMD || KK0081.GENE_ADD_DTM) =   ");
		sbSql.append("       (SELECT KK0081_GENE.SVC_KEI_NO, MAX(KK0081_GENE.RSV_APLY_YMD || KK0081_GENE.GENE_ADD_DTM) AS KK0081_MAX  ");
		sbSql.append("        FROM   KK_T_SVC_KEI KK0081_GENE  ");
		sbSql.append("        WHERE  KK0081_GENE.SVC_KEI_NO = KK0081.SVC_KEI_NO  ");
		sbSql.append("        AND    KK0081_GENE.RSV_APLY_CD = '2'  ");
		sbSql.append("        AND    KK0081_GENE.RSV_APLY_YMD <= ?  ");
		sbSql.append("        AND    KK0081_GENE.MK_FLG = '0'  ");
		sbSql.append("        GROUP BY KK0081_GENE.SVC_KEI_NO) ");
		sbSql.append(" AND   (KK0021.MSKM_DTL_NO, KK0021.GENE_ADD_DTM) =  ");
		sbSql.append("       (SELECT KK0021_GENE.MSKM_DTL_NO, MAX(KK0021_GENE.GENE_ADD_DTM) AS KK0021_MAX  ");
		sbSql.append("        FROM KK_T_MSKM_DTL KK0021_GENE  ");
		sbSql.append("        WHERE KK0021_GENE.MSKM_DTL_NO = KK0021.MSKM_DTL_NO  ");
		sbSql.append("        AND   KK0021_GENE.MK_FLG = '0'  ");
		sbSql.append("        GROUP BY KK0021_GENE.MSKM_DTL_NO)  ");
		sbSql.append(" AND  (NOT EXISTS ( ");
		sbSql.append("                 SELECT  1  ");
		sbSql.append("                 FROM    KK_M_SHOSA_TRN_JOKEN KK2001 ");
		sbSql.append("                 WHERE   KK2001.SHOSA_TRN_JOKEN_CD = '00001'  ");
		sbSql.append("                 AND     KK2001.AUTO_SHOSA_TG_SVC_CD = KK0081.SVC_CD  ");
		sbSql.append("                 AND     KK2001.AUTO_SHOSA_TG_PRC_GRP_CD = KK0081.PRC_GRP_CD  ");
		sbSql.append("                 AND     KK2001.AUTO_SHOSA_TG_PCRS_CD = KK0081.PCRS_CD  ");
		sbSql.append("                 AND     KK2001.AUTO_SHOSA_TG_PPLAN_CD = KK0081.PPLAN_CD  ");
		sbSql.append("                 AND     KK2001.SHOSA_TRN_JOKEN_TSTAYMD <= ?  ");
		sbSql.append("                 AND     KK2001.SHOSA_TRN_JOKEN_TENDYMD >= ?  ");
		sbSql.append("                 AND    (KK2001.SHOSA_TRN_JOKEN_CD, KK2001.SHOSA_TRN_JOKEN_DTL_NO, KK2001.RSV_APLY_YMD || KK2001.GENE_ADD_DTM) =   ");
		sbSql.append("                        (SELECT KK2001_GENE.SHOSA_TRN_JOKEN_CD, KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO, MAX(KK2001_GENE.RSV_APLY_YMD || KK2001_GENE.GENE_ADD_DTM) AS KK2001_MAX  ");
		sbSql.append("                         FROM   KK_M_SHOSA_TRN_JOKEN KK2001_GENE  ");
		sbSql.append("                         WHERE  KK2001_GENE.SHOSA_TRN_JOKEN_CD = KK2001.SHOSA_TRN_JOKEN_CD  ");
		sbSql.append("                         AND    KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO = KK2001.SHOSA_TRN_JOKEN_DTL_NO  ");
		sbSql.append("                         AND    KK2001_GENE.RSV_APLY_YMD <= ?  ");
		sbSql.append("                         AND    KK2001_GENE.MK_FLG = '0'  ");
		sbSql.append("                         GROUP BY KK2001_GENE.SHOSA_TRN_JOKEN_CD, KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO)  ");
		sbSql.append("        )  ");
		sbSql.append("  OR  NOT EXISTS ( ");
		sbSql.append("                 SELECT  1  ");
		sbSql.append("                 FROM    KK_M_SHOSA_TRN_JOKEN KK2001 ");
		sbSql.append("                 WHERE   KK2001.SHOSA_TRN_JOKEN_CD = '00002'  ");
		sbSql.append("                 AND     KK2001.AUTO_SHOSA_TG_MSKM_FORM_CD = KK0021.MSKM_FORM_CD  ");
		sbSql.append("                 AND     KK2001.SHOSA_TRN_JOKEN_TSTAYMD <= ?  ");
		sbSql.append("                 AND     KK2001.SHOSA_TRN_JOKEN_TENDYMD >= ?  ");
		sbSql.append("                 AND    (KK2001.SHOSA_TRN_JOKEN_CD, KK2001.SHOSA_TRN_JOKEN_DTL_NO, KK2001.RSV_APLY_YMD || KK2001.GENE_ADD_DTM) =   ");
		sbSql.append("                        (SELECT KK2001_GENE.SHOSA_TRN_JOKEN_CD, KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO, MAX(KK2001_GENE.RSV_APLY_YMD || KK2001_GENE.GENE_ADD_DTM) AS KK2001_MAX  ");
		sbSql.append("                         FROM   KK_M_SHOSA_TRN_JOKEN KK2001_GENE  ");
		sbSql.append("                         WHERE  KK2001_GENE.SHOSA_TRN_JOKEN_CD = KK2001.SHOSA_TRN_JOKEN_CD  ");
		sbSql.append("                         AND    KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO = KK2001.SHOSA_TRN_JOKEN_DTL_NO  ");
		sbSql.append("                         AND    KK2001_GENE.RSV_APLY_YMD <= ?  ");
		sbSql.append("                         AND    KK2001_GENE.MK_FLG = '0'  ");
		sbSql.append("                         GROUP BY KK2001_GENE.SHOSA_TRN_JOKEN_CD, KK2001_GENE.SHOSA_TRN_JOKEN_DTL_NO)  ");
		sbSql.append("       ))  ");

		try
		{

			//コネクション取得
			con = JSYejbConnection.getConnection(KK0081ETMsg.getTableName());

			//prepareStatementにSQL文をセット
			pstmt = con.prepareStatement(sbSql.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), sbSql);

			// バインド変数設定
			CAANJDBCUtil.setParam(pstmt, 1, msg0021.getString(KK0021ETMsg.MSKM_NO));
			CAANJDBCUtil.setParam(pstmt, 2, msg0081.getString(KK0081ETMsg.SVC_KEI_NO));
			CAANJDBCUtil.setParam(pstmt, 3, opeDate);
			CAANJDBCUtil.setParam(pstmt, 4, opeDate);
			CAANJDBCUtil.setParam(pstmt, 5, opeDate);
			CAANJDBCUtil.setParam(pstmt, 6, opeDate);
			CAANJDBCUtil.setParam(pstmt, 7, opeDate);
			CAANJDBCUtil.setParam(pstmt, 8, opeDate);
			CAANJDBCUtil.setParam(pstmt, 9, opeDate);

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			if (rsltQuery.next())
			{
				if(rsltQuery.getInt("CNT") > 0)
				{
					return false;
				}
			}
			return true;

		}
		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);
			}
		}
	}
}
