/*******************************************************************************
*	 All Rights reserved,Copyright (c) K-Opticom 
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JSYejbEKK1311B001TPDA
*	ソースファイル名：JSYejbEKK1311B001TPDA.java
*	作成者			：EK909308
*	日付			：2011年10月26日
*＜機能概要＞
*	SQLFacility
*	テンプレートDBアクセス部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	ｖ1.00.00
*	ｖ4.00.00	2013/01/31	FJ）藤本	ST4-2013-0000094
*
********************************************************************************/

package eo.ejb.cbs.sqlf;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANSQLFacility;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
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.TemplateDBAccessHandler;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import eo.ejb.cbs.cbsmsg.EKK1311B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1311B001CBSMsg1List;
import eo.ejb.cbm.entity.KK1311ETMsg;
import eo.ejb.common.JKKModelCommon;

/**
*
*  テンプレートDBアクセス部品　EKK1311B001_SQLF<br>
*  入力された項目からSQL文を動的に組み立て、<br>
*  検索結果をCBSMsgにセットします。<br>
*/
public class JSYejbEKK1311B001TPDA extends CAANSQLFacility implements TemplateDBAccessHandler{
	
	/**
	 * コンストラクタ
	 */
	public JSYejbEKK1311B001TPDA()	{
	}
	
	/**
	*   EKK1311B001_SQLF<br>
	*   @param inMsg    入力値の格納されたCBSMsg <br>
	*   @return void
	*/
	public void invoke(CAANMsg inMsg,AgentDispatchContext inContext){
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		/******************** 
		 * SQL文の作成
		 ********************/

		try{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK1311ETMsg.getTableName());
			
			// パラメータ格納用のリスト
			ArrayList<Object> arrayParam = new ArrayList<Object>();
			
			// SQL文_基本部1
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT KK1311.SHUK_YM ")
					.append("       ,KK1311.OP_SVC_CD ")
					.append("       ,(SELECT KK0821.OP_SVC_NM ")
					.append("         FROM KK_M_OP_SVC KK0821 ")
					.append("         WHERE KK0821.OP_SVC_CD = KK1311.OP_SVC_CD ")
					.append("           AND (KK0821.OP_SVC_CD, KK0821.RSV_APLY_YMD || KK0821.GENE_ADD_DTM) = ")
					.append("              (SELECT KK0821_GENE.OP_SVC_CD, MAX(KK0821_GENE.RSV_APLY_YMD || KK0821_GENE.GENE_ADD_DTM) ")
					.append("               FROM KK_M_OP_SVC KK0821_GENE ")
					.append("               WHERE KK0821_GENE.OP_SVC_CD = KK0821.OP_SVC_CD ")
					.append("                 AND KK0821_GENE.RSV_APLY_YMD <= ? ")
					.append("                 AND KK0821_GENE.MK_FLG = '0' ")
					.append("                 GROUP BY KK0821_GENE.OP_SVC_CD) ")
					.append("        ) AS OP_SVC_NM ")
					.append("       ,KK1311.SVC_KEI_NO ")
					.append("       ,KK1311.SVC_KEI_UCWK_NO ")
					.append("       ,KK1311.TV_KEI_STAT_CD ")
					.append("       ,KK1311.KIKI_SEIZO_NO ")
					.append("       ,KK1311.STB_ID ")
					.append("       ,KK1311.UPD_DTM ")
					.append("       ,KK1311.SYSID ")
					.append(" FROM KK_T_TV_OP_WATCH_JSK KK1311 ");

			// バインド変数設定リストの更新（運用日付）
			arrayParam.add(JKKModelCommon.getOpeDate(inMsg));
			
			// SQL文_個別部1
			if ( "1".equals( inMsg.getObject(EKK1311B001CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE EXISTS (SELECT * ")
						.append("               FROM (SELECT KK1311_01.SHUK_YM ")
						.append("                           ,KK1311_01.SVC_KEI_NO ")
						.append("                           ,MAX(KK1311_01.OP_SVC_CD || KK1311_01.SVC_KEI_UCWK_NO) AS MAX_CD ")
						.append("                     FROM KK_T_TV_OP_WATCH_JSK KK1311_01 ")
						.append("                     WHERE KK1311_01.SHUK_YM = ? ");
 				
 				// バインド変数設定リストの更新(集計年月)
 				arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
 				
 				// オプションサービスコードのIN句をAND条件で連結
 				setOpSvcCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
 				
 				// TV契約状態コードのAND条件を連結
 				setTvKeiStatCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
 				
 				sql_Buff.append("                       AND KK1311_01.MK_FLG = '0' ")
						.append("                     GROUP BY KK1311_01.SHUK_YM,KK1311_01.SVC_KEI_NO ")
						.append("                    ) KK1311_02 ")
						.append("               WHERE KK1311_02.SHUK_YM = KK1311.SHUK_YM ")
						.append("                 AND KK1311_02.SVC_KEI_NO = KK1311.SVC_KEI_NO ")
						.append("                 AND KK1311_02.MAX_CD = (KK1311.OP_SVC_CD || KK1311.SVC_KEI_UCWK_NO) ")
						.append("               ) ");
			}
			if ( "2".equals( inMsg.getObject(EKK1311B001CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE KK1311.MK_FLG = '0' ")
						.append("   AND KK1311.SHUK_YM = ? ");
 						
 				// バインド変数設定リストの更新(集計年月)
		 		arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
		 		
		 		// オプションサービスコードのIN句をAND条件で連結
		 		setOpSvcCd(inMsg, sql_Buff, "KK1311", arrayParam);
		 		
		 		// TV契約状態コードのAND条件を連結
		 		setTvKeiStatCd(inMsg, sql_Buff, "KK1311", arrayParam);
						
				sql_Buff.append("   AND NOT EXISTS( ")
						.append("            SELECT * ")
						.append("            FROM KK_T_TV_OP_WATCH_JSK KK1311_01 ")
						.append("            WHERE KK1311_01.SVC_KEI_NO = KK1311.SVC_KEI_NO ")
						.append("              AND KK1311_01.STB_ID = KK1311.STB_ID ")
						.append("              AND KK1311_01.SHUK_YM = TO_CHAR(ADD_MONTHS(( ? || '01'),-1),'YYYYMM') ");
						
				// バインド変数設定リストの更新(集計年月)
		 		arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
		 		
		 		// オプションサービスコードのIN句をAND条件で連結
		 		setOpSvcCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
		 		
		 		// TV契約状態コードのAND条件を連結
		 		setTvKeiStatCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
						
		 		sql_Buff.append("              AND KK1311.MK_FLG = '0' ")
						.append("           ) ");
			}
			if ( "3".equals( inMsg.getObject(EKK1311B001CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE KK1311.MK_FLG = '0' ")
						.append("   AND KK1311.SHUK_YM = TO_CHAR(ADD_MONTHS(( ? || '01'),-1),'YYYYMM') ");
 				
 				// バインド変数設定リストの更新(集計年月)
		 		arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
		 		
		 		// オプションサービスコードのIN句をAND条件で連結
		 		setOpSvcCd(inMsg, sql_Buff, "KK1311", arrayParam);
		 		
		 		// TV契約状態コードのAND条件を連結
		 		setTvKeiStatCd(inMsg, sql_Buff, "KK1311", arrayParam);
		 		
				sql_Buff.append("   AND NOT EXISTS( ")
						.append("            SELECT * ")
						.append("            FROM KK_T_TV_OP_WATCH_JSK KK1311_01 ")
						.append("            WHERE KK1311_01.SVC_KEI_NO = KK1311.SVC_KEI_NO ")
						.append("              AND KK1311_01.STB_ID = KK1311.STB_ID ")
						.append("              AND KK1311_01.SHUK_YM = ? ");
 				
				// バインド変数設定リストの更新(集計年月)
		 		arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
		 		
		 		// オプションサービスコードのIN句をAND条件で連結
		 		setOpSvcCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
		 		
		 		// TV契約状態コードのAND条件を連結
		 		setTvKeiStatCd(inMsg, sql_Buff, "KK1311_01", arrayParam);
		 		
		 		sql_Buff.append("              AND KK1311.MK_FLG = '0' ")
						.append("           ) ");
			}
			if ( "4".equals( inMsg.getObject(EKK1311B001CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE KK1311.MK_FLG = '0' ")
						.append("   AND KK1311.SHUK_YM = ? ");
 						
 				// バインド変数設定リストの更新(集計年月)
		 		arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_SHUK_YM));
		 		
		 		// オプションサービスコードのIN句をAND条件で連結
		 		setOpSvcCd(inMsg, sql_Buff, "KK1311", arrayParam);
		 		
		 		// TV契約状態コードのAND条件を連結
		 		setTvKeiStatCd(inMsg, sql_Buff, "KK1311", arrayParam);
						
		 		sql_Buff.append(" ORDER BY KK1311.SVC_KEI_NO ASC ")
		 		        .append("          ,KK1311.SVC_KEI_UCWK_NO ASC ")
  		                .append("          ,KK1311.OP_SVC_CD ASC ");
			}
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			for(int i = 0; i < arrayParam.size(); i++)
			{
				CAANJDBCUtil.setParam(pstmt, (i + 1), arrayParam.get(i));
			}
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// EKK1311B001CBSMsgの明細にセットする項目
			String[] msgKeyList1 = {
					  EKK1311B001CBSMsg1List.SHUK_YM
					, EKK1311B001CBSMsg1List.OP_SVC_CD
					, EKK1311B001CBSMsg1List.OP_SVC_NM
					, EKK1311B001CBSMsg1List.SVC_KEI_NO
					, EKK1311B001CBSMsg1List.SVC_KEI_UCWK_NO
					, EKK1311B001CBSMsg1List.TV_KEI_STAT_CD
					, EKK1311B001CBSMsg1List.KIKI_SEIZO_NO
					, EKK1311B001CBSMsg1List.STB_ID
					, EKK1311B001CBSMsg1List.UPD_DTM
					, EKK1311B001CBSMsg1List.SYSID
			};
			
			// 明細に処理結果(ResultSet)をマッピング
			CAANMsg[] outMsg1 = mapMessageList(rsltQuery,msgKeyList1,"eo.ejb.cbs.cbsmsg.EKK1311B001CBSMsg1List",0);
			// inMsg(CBSMsg)に明細をセット
			inMsg.set("EKK1311B001CBSMsg1List", outMsg1);
			

		} catch(SQLException e) {
			inMsg.set(EKK1311B001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		} finally {
			// 資源の解放
			try{
				if(rsltQuery != null){
					rsltQuery.close();
				}
				if(pstmt != null){
					pstmt.close();
				}
				if(con1 != null){
					closeConnection(con1);
				}
			}catch(SQLException e){
				inMsg.set(EKK1311B001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}
	
	/**
	*   オプションサービスコードを設定するSQL文とバインド変数リストの生成を行う
	*   @param inMsg 入力値の格納されたCBSMsg
	*   @param sqlBuf SQL文を格納するバッファ
	*   @param nm 別名
	*   @param arrayParam バインド変数のリスト
	*   
	*/
	private void setOpSvcCd(CAANMsg inMsg, StringBuffer sqlBuf, String nm, ArrayList<Object> arrayParam)
	{
		StringBuffer bindBuf = new StringBuffer();
		
		// オプションサービスコード１
		setOpSvcCd(inMsg, EKK1311B001CBSMsg.KEY_OP_SVC_CD_1, bindBuf, arrayParam);
		
		// オプションサービスコード２
		setOpSvcCd(inMsg, EKK1311B001CBSMsg.KEY_OP_SVC_CD_2, bindBuf, arrayParam);

		// オプションサービスコード３
		setOpSvcCd(inMsg, EKK1311B001CBSMsg.KEY_OP_SVC_CD_3, bindBuf, arrayParam);
		
		// バインド変数が1つでも設定されている場合はIN句をAND条件で連結
		if(bindBuf.length() != 0)
		{
			sqlBuf.append( " AND ")
				.append(nm)
				.append(".OP_SVC_CD IN ( ")
				.append(bindBuf.toString())
				.append(" ) ");
		}
	}
	
	/**
	*   オプションサービスコードを設定するSQL文とバインド変数リストの生成を行う
	*   @param inMsg 入力値の格納されたCBSMsg
	*   @param key オブジェクトを取得するためのキー
	*   @param sqlBuf SQL文を格納するバッファ
	*   @param arrayParam バインド変数のリスト
	*   
	*/
	private void setOpSvcCd(CAANMsg inMsg, String key, StringBuffer bindBuf, ArrayList<Object> arrayParam)
	{
		// 指定のキーに紐づくオブジェクトに値が設定されている場合
		if(!inMsg.isNull(key))
		{
			// 既に1つ以上バインド変数を設定している場合は","で連結
			if(bindBuf.length() != 0)
			{
				bindBuf.append(" , ");
			}
			bindBuf.append(" ? ");
			
			// バインド変数設定リストの更新(オプションサービスコード)
			arrayParam.add(inMsg.getObject(key));
		}
	}
	
	/**
	*   TV契約状態コードを設定するSQL文とバインド変数リストの生成を行う
	*   @param inMsg 入力値の格納されたCBSMsg
	*   @param sqlBuf SQL文を格納するバッファ
	*   @param nm 別名
	*   @param arrayParam バインド変数のリスト
	*   
	*/
	private void setTvKeiStatCd(CAANMsg inMsg, StringBuffer sqlBuf, String nm, ArrayList<Object> arrayParam)
	{
		// サービスIF入力値：TV契約状態コードが指定されている場合
		if(!inMsg.isNull(EKK1311B001CBSMsg.KEY_TV_KEI_STAT_CD))
		{
			sqlBuf.append(" AND ")
				.append(nm)
				.append(".TV_KEI_STAT_CD = ? ");
			
			// バインド変数設定リストの更新(TV契約状態コード)
			arrayParam.add(inMsg.getObject(EKK1311B001CBSMsg.KEY_TV_KEI_STAT_CD));
		}
	}
}
