/*********************************************************************
*	All Rights reserved,Copyright c Fujitsu, 2011
**********************************************************************
*＜プログラム内容＞
*	システム名		：プロジェクト共通
*	モジュール名	：JACejbAC0171KRCK
*	ソースファイル名：JACejbAC0171KRCK.java
*	作成者			：富士通
*	日付			：2011年06月13日
*＜機能概要＞
*	一時金に関する制約部品を定義するクラスです。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/06/13	富士通		新規作成
*
**********************************************************************/
package eo.ejb.common.entity;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.fujitsu.futurity.model.base.CAANConnectionMgr;
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 eo.ejb.cbm.entity.AC0171ETMsg;
import eo.ejb.common.JPCModelCommon;
import eo.ejb.common.edit.JACejbEditString;
import eo.ejb.common.itemrelation.JACejbDateChecker;
import eo.ejb.cbm.cbmmsg.AC0171CBMMsg;
import eo.ejb.cbs.cbsmsg.EAC0171B010CBSMsg;

/**
 * 一時金に関する制約部品を定義するクラスです。<p>
 * <br>
 * @author 富士通
 */
public class JACejbAC0171KRCK
{

	/** サービス契約番号 文字サイズ */
	private static final int SIZE_SVC_KEI_NO = 10;

	/** 同月包含フラグ ON */
	private static final String INCLUDE_FLG_ON = "1";
	
	/** 同月包含フラグ OFF */
	private static final String INCLUDE_FLG_OFF = "0";

	/**
	 * <p>
	 * 重複登録判定処理
	 * </p>
	 * 一時金の重複登録判定を行います。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inSvcKeiNo サービス契約番号
	 * @param inPcrsCd 対象料金コースコード
	 * @param inProcSvcCd 対象料金サービスコード
	 * @param inProcKmkCd 対象料金項目コード
	 * @param inTonyuDiv 投入区分
	 * @param inSeikyYm 請求年月
	 * @return データが存在する場合はtrue。存在しない場合はfalse。
	 */
	public static boolean isDbleAdd(CAANMsg inMsg,
			AgentDispatchContext inContext, Object inSvcKeiNo, Object inPcrsCd,
			Object inProcSvcCd, Object inProcKmkCd, Object inTonyuDiv, Object inSeikyYm)

	{
		// 戻り値
		boolean bRtn = false;
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		// パラメータ設定可否
		boolean bKnkStat = false;			// 請求年月
		
		// パラメータの取得
		String sSvcKeiNo = (String)inSvcKeiNo;
		String sPcrsCd = (String)inPcrsCd;
		String sProcSvcCd = (String)inProcSvcCd;
		String sProcKmkCd = (String)inProcKmkCd;
		String sTonyuDiv = (String)inTonyuDiv;
		String sSeikyYm = (String)inSeikyYm;
		
		// パラメータインデックス
		int i = 1;
		
		/******************** 
		 * SQL文の作成
		 ********************/
		
		try
		{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(AC0171ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append(" COUNT(*) CNT ")
					.append(" FROM AC_T_ICJKN AC0171 ")
					.append(" WHERE AC0171.SVC_KEI_NO = ? ")
					.append("   AND AC0171.TRGT_PCRS_CD = ? ")
					.append("   AND AC0171.TRGT_PRC_SVC_CD = ? ")
					.append("   AND AC0171.TRGT_PRC_KMK_CD = ? ")
					.append("   AND AC0171.TONYU_DIV = ? ");
			
			// 請求年月がNULLの場合は「請求年月 IS NULL」の条件で検索する
			if (sSeikyYm == null)
			{
				sql_Buff.append(" AND AC0171.SEIKY_YM IS NULL ");
			}
			else
			{
				sql_Buff.append(" AND AC0171.SEIKY_YM = ? ");
				bKnkStat = true;
			}
			
			// 検索条件：一時金取込ステータス≠9（削除）
			sql_Buff.append("   AND AC0171.ICJKN_TRKM_STAT <> '9' ");
			sql_Buff.append("   AND AC0171.MK_FLG = '0' ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS,
					JACejbAC0171KRCK.class, sql_Buff);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			
			// サービス契約番号がNULLの場合はフル桁半角スペースで検索する
			if (sSvcKeiNo == null)
			{
				// サービス契約番号のフル桁半角スペースは
				// JACejbEditString.fillHalfSpace処理で編集する。
				sSvcKeiNo = JACejbEditString.fillHalfSpace(inMsg, inContext, "",
						SIZE_SVC_KEI_NO, true);
			}
			
			// パラメータの設定(サービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, sSvcKeiNo);
			// パラメータの設定(対象料金コースコードを指定)
			CAANJDBCUtil.setParam(pstmt, i++, sPcrsCd);
			// パラメータの設定(対象料金サービスコードを指定)
			CAANJDBCUtil.setParam(pstmt, i++, sProcSvcCd);
			// パラメータの設定(対象料金項目コードを指定)
			CAANJDBCUtil.setParam(pstmt, i++, sProcKmkCd);
			// パラメータの設定(投入区分を指定)
			CAANJDBCUtil.setParam(pstmt, i++, sTonyuDiv);
			// パラメータの設定(請求年月を指定)
			if (bKnkStat)
			{
				CAANJDBCUtil.setParam(pstmt, i++, sSeikyYm);
			}
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 戻り値の判定
			if (rsltQuery.next())
			{
				if (rsltQuery.getLong("CNT") > 0)
				{
					// 取得件数 > 0 の場合trueを返却する
					bRtn = true;
				}
			}
		}
		catch (SQLException e)
		{
			inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}

		return bRtn;
	}

	/**
	 * <p>
	 * 重複登録判定処理(更新用)
	 * </p>
	 * 入力パラメータを更新前の一時金から取得し、一時金の重複登録判定を行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inIcjknAddSeq 一時金登録番号
	 * @param inIcjknUpdSeq 一時金更新枝番
	 * @param inTonyuDiv 投入区分
	 * @param inSeikyYm 請求年月
	 * @return データが存在する場合はtrue。存在しない場合はfalse。
	 */
	public static boolean isDbleAddForUpd(CAANMsg inMsg,
			AgentDispatchContext inContext, Object inIcjknAddSeq,
			Object inIcjknUpdSeq, Object inTonyuDiv, Object inSeikyYm)
	{
		// 戻り値
		boolean bRtn = false;
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		// パラメータの取得
		String sIcjknAddSeq = (String)inIcjknAddSeq;
		String sIcjknUpdSeq = (String)inIcjknUpdSeq;
		
		// 一時金更新枝番がすでにカウントアップされているので
		// カウントダウンする。
		int iIcjknUpdSeq = 0;
		iIcjknUpdSeq = Integer.valueOf(inIcjknUpdSeq.toString().trim()) - 1;
		sIcjknUpdSeq = String.valueOf(iIcjknUpdSeq);
		
		// 一時金更新枝番が一桁の場合、先頭に0を付加する。
		if (1 == sIcjknUpdSeq.length())
		{
			sIcjknUpdSeq = "0" + sIcjknUpdSeq;
		}
		
		// パラメータインデックス
		int i = 1;
		
		/******************** 
		 * SQL文の作成
		 ********************/
		
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(AC0171ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT SVC_KEI_NO ")
					.append("       ,TRGT_PCRS_CD ")
					.append("       ,TRGT_PRC_SVC_CD ")
					.append("       ,TRGT_PRC_KMK_CD ")
					.append(" FROM AC_T_ICJKN AC0171 ")
					.append(" WHERE AC0171.ICJKN_ADD_SEQ = ? ")
					.append("   AND AC0171.ICJKN_UPD_SEQ = ? ")
					.append("   AND AC0171.MK_FLG = '0' ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS,
					JACejbAC0171KRCK.class, sql_Buff);
			
			// パラメータの設定(一時金登録番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, sIcjknAddSeq);
			// パラメータの設定(一時金更新枝番を指定)
			CAANJDBCUtil.setParam(pstmt, i++, sIcjknUpdSeq);
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 戻り値の判定
			if (rsltQuery.next())
			{
				// 「重複登録判定処理」メソッドを呼び出す。
				bRtn = isDbleAdd(inMsg, inContext,
						rsltQuery.getString("SVC_KEI_NO"),
						//対象料金コースコードがスキーマに存在しないためNULLを渡す 2011/06/29
						rsltQuery.getString("TRGT_PCRS_CD"),
						rsltQuery.getString("TRGT_PRC_SVC_CD"),
						rsltQuery.getString("TRGT_PRC_KMK_CD"),
						inTonyuDiv, inSeikyYm);
			}
		}
		catch (SQLException e)
		{
			inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			// 
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		
		return bRtn;
	}

	/**
	 * <p>
	 * 一時金更新枝番排他チェック処理
	 * </p>
	 * 更新対象の一時金の一時金更新枝番が最新かチェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inIcjknAddSeq 一時金登録番号
	 * @param inIcjknUpdSeq 一時金更新枝番
	 * @return 一時金更新枝番が最新の場合false、最新でない場合true
	 */
	public static boolean isjknUpdSeqExclusive(CAANMsg inMsg,
			AgentDispatchContext inContext, Object inIcjknAddSeq, Object inIcjknUpdSeq)
	{
		// 戻り値
		boolean bRtn = false;
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		// パラメータの取得
		String sIcjknAddSeq = (String)inIcjknAddSeq;
		String sIcjknUpdSeq = (String)inIcjknUpdSeq;
		
		int iIcjknUpdSeq = 0;
		iIcjknUpdSeq = Integer.valueOf(inIcjknUpdSeq.toString().trim()) - 1;
		sIcjknUpdSeq = String.valueOf(iIcjknUpdSeq);
		
		// 一時金更新枝番が一桁の場合、先頭に0を付加する。
		if (1 == sIcjknUpdSeq.length())
		{
			sIcjknUpdSeq = "0" + sIcjknUpdSeq;
		}
		
		/******************** 
		 * SQL文の作成
		 ********************/
		
		try
		{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(AC0171ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT MAX(AC0171.ICJKN_UPD_SEQ) AS ICJKN_UPD_SEQ_MAX ")
					.append(" FROM AC_T_ICJKN AC0171 ")
					.append(" WHERE AC0171.ICJKN_ADD_SEQ = ? ")
					.append(" AND   AC0171.MK_FLG = '0' ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS,
					JACejbAC0171KRCK.class, sql_Buff);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			
			// パラメータの設定(一時金登録番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, sIcjknAddSeq);
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 取得した一時金更新枝番とパラメータの一時金更新枝番を比較する。
			if (rsltQuery.next())
			{
				if(rsltQuery.getString("ICJKN_UPD_SEQ_MAX") == null)
				{
					// 比較結果が異なる場合はtrueを設定する。
					bRtn = true;
				}
				else if(!rsltQuery.getString("ICJKN_UPD_SEQ_MAX").equals(sIcjknUpdSeq.trim()))
				{
					// 比較結果が異なる場合はtrueを設定する。
					bRtn = true;
				}
			}
		}
		catch (SQLException e)
		{
			inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		return bRtn;
	}

	/**
	 * <p>
	 * 一時金更新枝番排他チェック処理
	 * </p>
	 * 更新対象の一時金の一時金更新枝番が最新かチェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inIcjknAddSeq 一時金登録番号
	 * @param inIcjknUpdSeq 一時金更新枝番
	 * @return 一時金更新枝番が最新の場合false、最新でない場合true
	 */
	public static boolean isjknUpdSeqExclusiveForCBS(CAANMsg inMsg,
			AgentDispatchContext inContext, Object inIcjknAddSeq, Object inIcjknUpdSeq)
	{
		// 戻り値
		boolean bRtn = false;
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		// パラメータの取得
		String sIcjknAddSeq = (String)inIcjknAddSeq;
		String sIcjknUpdSeq = (String)inIcjknUpdSeq;
		
		/******************** 
		 * SQL文の作成
		 ********************/
		
		try
		{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(AC0171ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT MAX(AC0171.ICJKN_UPD_SEQ) AS ICJKN_UPD_SEQ_MAX ")
					.append(" FROM AC_T_ICJKN AC0171 ")
					.append(" WHERE AC0171.ICJKN_ADD_SEQ = ? ")
					.append(" AND   AC0171.MK_FLG = '0' ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS,
					JACejbAC0171KRCK.class, sql_Buff);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			
			// パラメータの設定(一時金登録番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, sIcjknAddSeq);
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 取得した一時金更新枝番とパラメータの一時金更新枝番を比較する。
			if (rsltQuery.next())
			{
				if(rsltQuery.getString("ICJKN_UPD_SEQ_MAX") == null)
				{
					// 比較結果が異なる場合はtrueを設定する。
					bRtn = true;
				}
				else if(!rsltQuery.getString("ICJKN_UPD_SEQ_MAX").equals(sIcjknUpdSeq.trim()))
				{
					// 比較結果が異なる場合はtrueを設定する。
					bRtn = true;
				}
			}
		}
		catch (SQLException e)
		{
			inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inMsg.set(AC0171ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		return bRtn;
	}
	
	/**
	 * <p>
	 * 更新対象レコードの排他チェックを行う
	 * </p>
	 * 排他チェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inSchemaName スキーマ名
	 * @return 排他：false、排他でない：true
	 */
	public static boolean succeededExclusiveLock(CAANMsg inMsg, AgentDispatchContext inContext, Object inSchemaName)
	{
		// 一時金更新枝番がカウントアップされているため
		// 排他チェックのためにカウントダウンする。
		String inIcjknUpdSeq = inMsg.getString(AC0171ETMsg.ICJKN_UPD_SEQ);
		String inIcjknUpdSeqMt = inMsg.getString(AC0171ETMsg.ICJKN_UPD_SEQ);
		
		int iIcjknUpdSeq = 0;
		iIcjknUpdSeq = Integer.valueOf(inIcjknUpdSeq.trim()) - 1;
		String sIcjknUpdSeq = String.valueOf(iIcjknUpdSeq);
		
		// 一時金更新枝番が一桁の場合、先頭に0を付加する。
		if (1 == sIcjknUpdSeq.length())
		{
			sIcjknUpdSeq = "0" + sIcjknUpdSeq;
		}
		
		inMsg.set(AC0171ETMsg.ICJKN_UPD_SEQ, sIcjknUpdSeq);
		
		boolean ret = JPCModelCommon.succeededExclusiveLock(inMsg, inContext, inSchemaName);
		
		// 一時金更新枝番を元に戻す。
		inMsg.set(AC0171ETMsg.ICJKN_UPD_SEQ, inIcjknUpdSeqMt);
		
		return ret;
	}
	
}
