/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JSYejbEKK1351B001TPDA
*	ソースファイル名：JSYejbEKK1351B001TPDA.java
*	作成者			：EK103139
*	日付			：2012年01月31日
*＜機能概要＞
*	データ抽出項目一覧照会テンプレートDBアクセス部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	ｖ1.00.00
*	ｖ4.00.00   2013/06/12  FJ）竹内    IT1-2013-0001258
*
********************************************************************************/

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.common.constant.JPCModelConstant;
import eo.ejb.cbs.cbsmsg.EKK1351B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1351B001CBSMsg1List;
import eo.ejb.cbm.entity.KK1351ETMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKejbPagingUtil;

/**
*
*  テンプレートDBアクセス部品　EKK1351B001_SQLF<br>
*  入力された項目からSQL文を動的に組み立て、<br>
*  検索結果をCBSMsgにセットします。<br>
*/
public class JSYejbEKK1351B001TPDA extends CAANSQLFacility implements TemplateDBAccessHandler{
	
	/**
	 * 時分（0000）
	 */
	private static final String SUFFIX_START = "0000"; 
	
	/**
	 * 時分（2359）
	 */
	private static final String SUFFIX_END = "2359";
	
	/** 
	 * ソート区分用（昇順)
	 */
	private static final String SORT_ASC = "1";

	/** 
	 * ソート区分用（降順)
	 */
	private static final String SORT_DESC = "2";
	
	/** 
	 * ソート項目用（表示用データ抽出項目コード)
	 */
	private static final String SORT_DSP_DCHSKM_CD = "1";

	/** 
	 * ソート項目用（設定可能開始年月日時分)
	 */
	private static final String SORT_SET_PSB_STA_YMDHM = "2";

	/** 
	 * ソート項目用（設定可能終了年月日時分)
	 */
	private static final String SORT_SET_PSB_END_YMDHM = "3";
	
	/**
	 * コンストラクタ
	 */
	public JSYejbEKK1351B001TPDA()	{
	}
	
	/**
	*   EKK1351B001_SQLF<br>
	*   @param inMsg    入力値の格納されたCBSMsg <br>
	*   @return void
	*/
	public void invoke(CAANMsg inMsg,AgentDispatchContext inContext){
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt_Count = null;
		PreparedStatement pstmt_Page = null;

		// リザルトセット
		ResultSet rsltQuery_Count = null;
		ResultSet rsltQuery_Page = null;
		
		/******************** 
		 * SQL文の作成
		 ********************/

		try{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK1351ETMsg.getTableName());

			// バインド変数設定値保持用領域
			ArrayList<Object> arrayParam = new ArrayList<Object>();

			// SQL文の作成(ページングヘッダ)
			// (1-1)
			StringBuffer sql_Buff1_1 = new StringBuffer();
			sql_Buff1_1.append(" SELECT * ")
						.append(" FROM ( SELECT ALL_SELECT.*, ROWNUM AS LINE ")
						.append("        FROM ( ");

			// SQL文の作成(件数取得用)
			// (2)
			StringBuffer sql_Buff2 = new StringBuffer();
			sql_Buff2.append(" SELECT COUNT(*) AS CNT ");
			
			// SQL文の作成(項目取得用)
			// (3)
			StringBuffer sql_Buff3 = new StringBuffer();
			if ("1".equals(inMsg.getObject(EKK1351B001CBSMsg.FUNC_CODE).toString()))
			{
				sql_Buff3.append(" SELECT KK1351_01.DSP_DCHSKM_CD, ")
						.append("        KK1351_01.DCHSKM_NM, ")
						.append("        KK1351_01.SET_PSB_STA_YMDHM, ")
						.append("        KK1351_01.SET_PSB_END_YMDHM, ")
						.append("        KK1351_01.DCHSKM_CD, ")
						.append("        KK1351_01.GDS_HASSO_SK_AD_SKBT_CD, ")
						.append("        KK1351_01.SHOHINK_AMNT, ")
						.append("        KK1351_01.AISTJ_PRINT_MONGON_SKBT_CD ");
			}
			else if ("2".equals(inMsg.getObject(EKK1351B001CBSMsg.FUNC_CODE).toString()))
			{
				sql_Buff3.append(" SELECT KK1351_02.DSP_DCHSKM_CD, ")
						.append("        KK1351_02.DCHSKM_NM, ")
						.append("        KK1351_02.SET_PSB_STA_YMDHM, ")
						.append("        KK1351_02.SET_PSB_END_YMDHM, ")
						.append("        NULL AS DCHSKM_CD, ")
						.append("        NULL AS GDS_HASSO_SK_AD_SKBT_CD, ")
						.append("        NULL AS SHOHINK_AMNT, ")
						.append("        NULL AS AISTJ_PRINT_MONGON_SKBT_CD ");
			}

			// SQL文の作成(レコード集約ヘッダ)
			// (6-1)
			StringBuffer sql_Buff6_1 = new StringBuffer();
			if ("2".equals(inMsg.getObject(EKK1351B001CBSMsg.FUNC_CODE).toString()))
			{
				sql_Buff6_1.append(" FROM ( ")
							.append("     SELECT KK1351_01.DSP_DCHSKM_CD, ")
							.append("            KK1351_01.DCHSKM_NM, ")
							.append("            KK1351_01.SET_PSB_STA_YMDHM, ")
							.append("            KK1351_01.SET_PSB_END_YMDHM, ")
							.append("            NULL AS DCHSKM_CD, ")
							.append("            NULL AS GDS_HASSO_SK_AD_SKBT_CD, ")
							.append("            NULL AS SHOHINK_AMNT, ")
							.append("            NULL AS AISTJ_PRINT_MONGON_SKBT_CD ");
			}

			// SQL文の作成(検索条件ヘッダ)
			// (4-1)
			StringBuffer sql_Buff4_1 = new StringBuffer();
			sql_Buff4_1.append(" FROM ( ")
						.append("     SELECT KK1351.DSP_DCHSKM_CD, ")
						.append("            KK1351.DCHSKM_NM, ")
						.append("            KK1351.SET_PSB_STA_YMDHM, ")
						.append("            KK1351.SET_PSB_END_YMDHM, ")
						.append("            KK1351.DCHSKM_CD, ")
						.append("            KK1351.GDS_HASSO_SK_AD_SKBT_CD, ")
						.append("            KK1351.SHOHINK_AMNT, ")
						.append("            KK1351.AISTJ_PRINT_MONGON_SKBT_CD, ")
						.append("            ROW_NUMBER() OVER (PARTITION BY KK1351.DSP_DCHSKM_CD, KK1351.DCHSKM_NM, KK1351.SET_PSB_STA_YMDHM, KK1351.SET_PSB_END_YMDHM ORDER BY 1, 2, 3, 4) AS LINE ")
						.append("     FROM   KK_M_DCHSKM KK1351 ")
						.append("     WHERE (KK1351.DCHSKM_CD, KK1351.RSV_APLY_YMD || KK1351.GENE_ADD_DTM) = ") 
						.append("        (SELECT KK1351_GENE.DCHSKM_CD, MAX(KK1351_GENE.RSV_APLY_YMD || KK1351_GENE.GENE_ADD_DTM) AS KK1351_MAX ")
						.append("         FROM   KK_M_DCHSKM KK1351_GENE ")
						.append("         WHERE  KK1351_GENE.DCHSKM_CD = KK1351.DCHSKM_CD ")
						.append("         AND    KK1351_GENE.RSV_APLY_YMD <= ? ")
						.append("         AND    KK1351_GENE.MK_FLG = '0' ")
						.append("         GROUP BY KK1351_GENE.DCHSKM_CD ) ");

			// バインドリストの設定（運用日付）
			arrayParam.add(JKKModelCommon.getOpeDate(inMsg));

			//検索条件を追加（KEY_DCHS_TYPE_CD）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_DCHS_TYPE_CD))
			{
				String[] dchsTypeCds = inMsg.getString(EKK1351B001CBSMsg.KEY_DCHS_TYPE_CD).split(",");
				sql_Buff4_1.append("      AND    KK1351.DCHS_TYPE_CD IN ( ");
				
				for (int cnt = 0; cnt < dchsTypeCds.length; cnt++)
				{
					if (cnt > 0)
					{
						sql_Buff4_1.append(",");
					}
					sql_Buff4_1.append(" ? ");

					// バインドリストの設定（データ抽出タイプコード）
					arrayParam.add(dchsTypeCds[cnt]);
				}
				sql_Buff4_1.append(" ) ");
			}
			
			//検索条件を追加（KEY_DCHS_APLY_OPTNTY_CD）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_DCHS_APLY_OPTNTY_CD))
			{
				sql_Buff4_1.append("     AND    KK1351.DCHS_APLY_OPTNTY_CD = ? ");

				// バインドリストの設定（ＫＥＹ＿データ抽出適用契機コード）
				arrayParam.add(inMsg.getObject(EKK1351B001CBSMsg.KEY_DCHS_APLY_OPTNTY_CD));
			}
			//検索条件を追加（KEY_MSKM_YMD）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_MSKM_YMD))
			{
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_STA_YMDHM <= ?  ");
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_END_YMDHM >= ?  ");

				// バインドリストの設定（ＫＥＹ＿申込年月日）
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_MSKM_YMD).concat(SUFFIX_END));
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_MSKM_YMD).concat(SUFFIX_START));
			}
			//検索条件を追加（KEY_SET_PSB_STA_YMD_FROM）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_SET_PSB_STA_YMD_FROM))
			{
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_STA_YMDHM >= ?  ");

				// バインドリストの設定（ＫＥＹ＿設定可能開始年月日（自））
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_SET_PSB_STA_YMD_FROM).concat(SUFFIX_START));
			}
			//検索条件を追加（KEY_SET_PSB_STA_YMD_TO）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_SET_PSB_STA_YMD_TO))
			{
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_STA_YMDHM <= ?  ");

				// バインドリストの設定（ＫＥＹ＿設定可能開始年月日（至））
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_SET_PSB_STA_YMD_TO).concat(SUFFIX_END));
			}
			//検索条件を追加（KEY_SET_PSB_END_YMD_FROM）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_SET_PSB_END_YMD_FROM))
			{
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_END_YMDHM >= ?  ");

				// バインドリストの設定（ＫＥＹ＿設定可能終了年月日（自））
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_SET_PSB_END_YMD_FROM).concat(SUFFIX_START));
			}
			//検索条件を追加（KEY_SET_PSB_END_YMD_TO）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_SET_PSB_END_YMD_TO))
			{
				sql_Buff4_1.append("     AND    KK1351.SET_PSB_END_YMDHM <= ?  ");

				// バインドリストの設定（ＫＥＹ＿設定可能終了年月日（至））
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_SET_PSB_END_YMD_TO).concat(SUFFIX_END));
			}
			//検索条件を追加（KEY_DSP_DCHSKM_CD）
			if (!inMsg.isNull(EKK1351B001CBSMsg.KEY_DSP_DCHSKM_CD))
			{
				sql_Buff4_1.append("     AND    KK1351.DSP_DCHSKM_CD = ? ");

				// バインドリストの設定（ＫＥＹ＿表示用データ抽出項目コード）
				arrayParam.add(inMsg.getString(EKK1351B001CBSMsg.KEY_DSP_DCHSKM_CD));
			}

			// SQL文の作成(ORDER BY句)
			// (5)
			StringBuffer sql_Buff5 = new StringBuffer();
			
			// ＫＥＹ＿ソート項目Ｎｏによってソート条件を結合する。
	 		// ソート区分判定
			String strSortKbn = null;
			if (SORT_ASC.equals(inMsg.getObject(EKK1351B001CBSMsg.KEY_SORT_KBN)))
			{
				// ＫＥＹ＿ソート区分が"1"(昇順)の場合
				strSortKbn = " ASC ";
			}
			else if (SORT_DESC.equals(inMsg.getObject(EKK1351B001CBSMsg.KEY_SORT_KBN)))
			{
				// ＫＥＹ＿ソート区分が"2"(降順)の場合
				strSortKbn = " DESC ";
			}
			else
			{
				strSortKbn = "";
			}
			
			// ソート項目判定
			sql_Buff5.append("ORDER BY " );
			if (SORT_DSP_DCHSKM_CD.equals(inMsg.getObject(EKK1351B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK1351.DSP_DCHSKM_CD ")
						.append(strSortKbn)
						.append(",");
			}
			else if (SORT_SET_PSB_STA_YMDHM.equals(inMsg.getObject(EKK1351B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK1351.SET_PSB_STA_YMDHM ")
						.append(strSortKbn)
						.append(",");
			}
			else if (SORT_SET_PSB_END_YMDHM.equals(inMsg.getObject(EKK1351B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK1351.SET_PSB_END_YMDHM ")
						.append(strSortKbn)
						.append(",");
			}
			
			sql_Buff5.append("KK1351.DSP_JUN ASC ");

			// SQL文の作成(検索条件フッタ)
			// (4-2)
			StringBuffer sql_Buff4_2 = new StringBuffer();
			sql_Buff4_2.append(" ) KK1351_01 ");

			// SQL文の作成(レコード集約フッタ)
			// (6-2)
			StringBuffer sql_Buff6_2 = new StringBuffer();
			if ("2".equals(inMsg.getObject(EKK1351B001CBSMsg.FUNC_CODE).toString()))
			{
				sql_Buff6_2.append(" WHERE KK1351_01.LINE = 1 ")
							.append(" ) KK1351_02 ");
			}

			// SQL文の作成(ページングフッタ)
			// (1-2)
			StringBuffer sql_Buff1_2 = new StringBuffer();
			sql_Buff1_2.append("    ) ALL_SELECT  ")
						.append(") PAGE_SELECT  ")
						.append("WHERE PAGE_SELECT.LINE BETWEEN ? AND ?  ")
						.append("ORDER BY PAGE_SELECT.LINE ASC  ");
			
			// SQL文の組立て(件数取得用) (2) + (6-1) + (4-1) + (4-2) + (6-2)
			StringBuffer sql_Count = new StringBuffer();
			sql_Count.append(sql_Buff2)   // 件数取得
					.append(sql_Buff6_1)  // レコード集約ヘッダ
					.append(sql_Buff4_1)  // 検索条件ヘッダ
					.append(sql_Buff4_2)  // 検索条件フッタ
					.append(sql_Buff6_2); // レコード集約フッタ

			//prepareStatementにSQL文をセット
			pstmt_Count = con1.prepareStatement(sql_Count.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Count);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			for (int i = 0; i < arrayParam.size(); i++)
			{
				CAANJDBCUtil.setParam(pstmt_Count, (i + 1), arrayParam.get(i));
			}
			
			// ResultSetの取得
			rsltQuery_Count = pstmt_Count.executeQuery();
			
			// 総検索件数を取得する
			long lDataCnt = 0L;
			if (rsltQuery_Count.next())
			{
				lDataCnt = rsltQuery_Count.getLong("CNT");
			}
			
			// 表示件数
			long lDispNum = inMsg.getStringAsLong(EKK1351B001CBSMsg.DISPLAY_NUM);
			
			// 表示ページ数
			long lDispPage = inMsg.getStringAsLong(EKK1351B001CBSMsg.DISPLAY_PAGE_NUM);
			
			// 最大取得件数
			long lMaxNum = inMsg.getStringAsLong(EKK1351B001CBSMsg.MAX_SEARCH_NUM);
			
			// 総ページ数
			String strMaxPage = JKKejbPagingUtil.calcTotalPage(lDataCnt, lDispNum);
			
			// 共通部に値を設定する
			inMsg.set(EKK1351B001CBSMsg.TOTAL_SEARCH_NUM, String.valueOf(lDataCnt));   // 総検索件数
			inMsg.set(EKK1351B001CBSMsg.TOTAL_PAGE_NUM, strMaxPage);   // 総ページ数
			
			// データ取得件数が0件の場合エラー
			if (0L == lDataCnt)
			{
				inMsg.set(EKK1351B001CBSMsg.SEARCH_ERR_FLG, JPCModelConstant.SEARCH_ERR_FLG_ZERO);
				return;
			}

			// 最大取得件数を超えた場合エラー
			if (lDataCnt > lMaxNum)
			{
				inMsg.set(EKK1351B001CBSMsg.SEARCH_ERR_FLG, JPCModelConstant.SEARCH_ERR_FLG_OVERMAX);
				return;
			}
			
			// SQL文の組立て(項目取得・ページング用) (1-1) + (3) + (6-1) + (4-1) + (5) + (4-2) + (6-2) + (1-2)
			StringBuffer sql_Page = new StringBuffer();
			sql_Page.append(sql_Buff1_1)  // ページングヘッダ
					.append(sql_Buff3)    // 項目取得
					.append(sql_Buff6_1)  // レコード集約ヘッダ
					.append(sql_Buff4_1)  // 検索条件ヘッダ
					.append(sql_Buff5)    // ソート条件
					.append(sql_Buff4_2)  // 検索条件フッタ
					.append(sql_Buff6_2)  // レコード集約フッタ
					.append(sql_Buff1_2); // ページングフッタ

			//prepareStatementにSQL文をセット
			pstmt_Page = con1.prepareStatement(sql_Page.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Page);
			
			// 検索対象行を算出する
			long[] lPages = JKKejbPagingUtil.calcSearchRows(lDispPage, lDispNum);
			long lRowSta = lPages[0];
			long lRowEnd = lPages[1];
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			int iParamCntr = 0;
			for (iParamCntr = 0; iParamCntr < arrayParam.size(); iParamCntr++)
			{
				CAANJDBCUtil.setParam(pstmt_Page, (iParamCntr + 1), arrayParam.get(iParamCntr));
			}
			// パラメータの設定(検索開始行を指定)
			CAANJDBCUtil.setParam(pstmt_Page, ++iParamCntr, lRowSta);
			// パラメータの設定(検索終了行を指定)
			CAANJDBCUtil.setParam(pstmt_Page, ++iParamCntr, lRowEnd);
			
			// ResultSetの取得
			rsltQuery_Page = pstmt_Page.executeQuery();
			
			// EKK1351B001CBSMsgの明細にセットする項目
			String[] msgKeyList1 = {
					  EKK1351B001CBSMsg1List.DSP_DCHSKM_CD
					, EKK1351B001CBSMsg1List.DCHSKM_NM
					, EKK1351B001CBSMsg1List.SET_PSB_STA_YMDHM
					, EKK1351B001CBSMsg1List.SET_PSB_END_YMDHM
					, EKK1351B001CBSMsg1List.DCHSKM_CD
					, EKK1351B001CBSMsg1List.GDS_HASSO_SK_AD_SKBT_CD
					, EKK1351B001CBSMsg1List.SHOHINK_AMNT
					, EKK1351B001CBSMsg1List.AISTJ_PRINT_MONGON_SKBT_CD
			};
			
			// 明細に処理結果(ResultSet)をマッピング
			CAANMsg[] outMsg1 = mapMessageList(rsltQuery_Page,msgKeyList1,"eo.ejb.cbs.cbsmsg.EKK1351B001CBSMsg1List",0);
			
			// 取得結果が0件の場合は表示ページ該当なしエラー
			if (0 >= outMsg1.length)
			{
				inMsg.set(EKK1351B001CBSMsg.SEARCH_ERR_FLG, JPCModelConstant.SEARCH_ERR_FLG_NODATA);
				return;
			}
			
			// inMsg(CBSMsg)に明細をセット
			inMsg.set("EKK1351B001CBSMsg1List", outMsg1);

		} catch(SQLException e) {
			inMsg.set(EKK1351B001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		} finally {
			// 資源の解放
			try{
				if(rsltQuery_Count != null)
				{
					rsltQuery_Count.close();
				}
				if(rsltQuery_Page != null)
				{
					rsltQuery_Page.close();
				}
				if(pstmt_Count != null)
				{
					pstmt_Count.close();
				}
				if(pstmt_Page != null)
				{
					pstmt_Page.close();
				}
				if(con1 != null)
				{
					closeConnection(con1);
				}
			}catch(SQLException e){
				inMsg.set(EKK1351B001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}
}
