/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JSYejbEKK0841B001TPDA
*	ソースファイル名：JSYejbEKK0841B001TPDA.java
*	作成者			：EK103139
*	日付			：2012年01月31日
*＜機能概要＞
*	割引サービス一覧照会テンプレートDBアクセス部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	ｖ1.00.00
*	ｖ4.00.00	2013/06/27	FJ）寺園	IT1-2013-0001258
*	ｖ9.00.00	2014/04/17	FJ）小島	ANK-2056-00-00
*
********************************************************************************/

package eo.ejb.cbs.sqlf;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

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.base.CAANSQLFacility;
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 com.fujitsu.futurity.model.ejb.common.fw.TemplateDBAccessHandler;

import eo.common.constant.JPCModelConstant;
import eo.ejb.cbm.entity.KK0841ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0841B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0841B001CBSMsg1List;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKejbPagingUtil;

/**
*
*  テンプレートDBアクセス部品　EKK0841B001_SQLF<br>
*  入力された項目からSQL文を動的に組み立て、<br>
*  検索結果をCBSMsgにセットします。<br>
*/
public class JSYejbEKK0841B001TPDA 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_CAMPAIGN_CD = "1";

	/** 
	 * ソート項目用（受付開始年月日時分)
	 */
	private static final String SORT_UK_STA_YMDHM = "2";

	/** 
	 * ソート項目用（受付終了年月日時分)
	 */
	private static final String SORT_UK_END_YMDHM = "3";
	
	/**
	 * コンストラクタ
	 */
	public JSYejbEKK0841B001TPDA()	{
	}
	
	/**
	*   EKK0841B001_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(KK0841ETMsg.getTableName());

			// バインド変数設定値保持用領域
			ArrayList<Object> arrayParam = new ArrayList<Object>();
			
			// SQL文の作成(ページングヘッダ)
			// (1-1)
			StringBuffer sql_Buff1_1 = new StringBuffer();
			sql_Buff1_1.append(" SELECT *  ")
						.append(" FROM (  ")
						.append("     SELECT ALL_SELECT.*, ROWNUM AS LINE  ")
						.append("     FROM (  ");

			// SQL文の作成(件数取得用)
			// (2)
			StringBuffer sql_Buff2 = new StringBuffer();
			sql_Buff2.append(" SELECT  ")
					.append("     COUNT(*) AS CNT  ");

			// SQL文の作成(項目取得用)
			// (3)
			StringBuffer sql_Buff3 = new StringBuffer();
			sql_Buff3.append(" SELECT KK0841_02.DSP_CAMPAIGN_CD, ")
					.append("        KK0841_02.WRIB_SVC_NM, ")
					.append("        KK0841_02.UK_STA_YMDHM, ")
					.append("        KK0841_02.UK_END_YMDHM ");

			// SQL文の作成(レコード集約ヘッダ)
			// (6-1)
			StringBuffer sql_Buff6_1 = new StringBuffer();
			sql_Buff6_1.append(" FROM ( ")
						.append("     SELECT KK0841_01.DSP_CAMPAIGN_CD, ")
						.append("            KK0841_01.WRIB_SVC_NM, ")
						.append("            KK0841_01.UK_STA_YMDHM, ")
						.append("            KK0841_01.UK_END_YMDHM ");

			// SQL文の作成(検索条件ヘッダ)
			// (4-1)
			StringBuffer sql_Buff4_1 = new StringBuffer();
			sql_Buff4_1.append(" FROM ( ")
						.append("     SELECT KK0841.DSP_CAMPAIGN_CD, ")
						.append("            KK0841.WRIB_SVC_NM, ")
						.append("            KK0841.UK_STA_YMDHM, ")
						.append("            KK0841.UK_END_YMDHM, ")
						.append("            ROW_NUMBER() OVER (PARTITION BY KK0841.DSP_CAMPAIGN_CD, KK0841.WRIB_SVC_NM, KK0841.UK_STA_YMDHM, KK0841.UK_END_YMDHM ORDER BY 1, 2, 3, 4) AS LINE ")
						.append("     FROM   KK_M_WRIB_SVC KK0841 ")
						.append("     WHERE (KK0841.WRIB_SVC_CD, KK0841.RSV_APLY_YMD || KK0841.GENE_ADD_DTM) = ")
						.append("        (SELECT KK0841_GENE.WRIB_SVC_CD, MAX(KK0841_GENE.RSV_APLY_YMD || KK0841_GENE.GENE_ADD_DTM) AS KK0841_MAX ")
						.append("         FROM   KK_M_WRIB_SVC KK0841_GENE ")
						.append("         WHERE  KK0841_GENE.WRIB_SVC_CD = KK0841.WRIB_SVC_CD ")
						.append("         AND    KK0841_GENE.RSV_APLY_YMD <= ? ")
						.append("         AND    KK0841_GENE.MK_FLG = '0' ")
						.append("         GROUP BY KK0841_GENE.WRIB_SVC_CD ) ");

			// バインドリストの設定（運用日付）
			arrayParam.add(JKKModelCommon.getOpeDate(inMsg));

			// ＫＥＹ＿割引タイプコードが設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_WRIB_TYPE_CD)) {
				sql_Buff4_1.append("     AND  KK0841.WRIB_TYPE_CD IN ( ");

				String[] sWribCd = inMsg.getString(EKK0841B001CBSMsg.KEY_WRIB_TYPE_CD).split(",");
				StringBuffer sbBindWribCd = new StringBuffer();

				for (int i = 0; i < sWribCd.length; i++)
				{
					// 入力値をカンマで分割した数分OR条件にて設定した内容を
					// AND条件にてWHERE句に設定する
					sbBindWribCd.append(" , ? ");

					// バインドリストの設定（割引タイプコード）
					arrayParam.add(sWribCd[i]);
				}

				// 最初のカンマを取り除いてSQLに設定
				sql_Buff4_1.append(sbBindWribCd.toString().substring(2))
							.append(" ) ");
			}

			// ＫＥＹ＿申込年月日が設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_MSKM_YMD)) {
				sql_Buff4_1.append("     AND    KK0841.UK_STA_YMDHM <= ? ")
							.append("     AND    ? <= KK0841.UK_END_YMDHM  ");

				// バインドリストの設定（ＫＥＹ＿申込年月日）
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_MSKM_YMD).concat(SUFFIX_END));
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_MSKM_YMD).concat(SUFFIX_START));
			}

			// ＫＥＹ＿受付開始年月日（自）が設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_UK_STA_YMD_FROM)) {
				sql_Buff4_1.append("     AND    ? <= KK0841.UK_STA_YMDHM ");

				// バインドリストの設定（ＫＥＹ＿受付開始年月日（自））
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_UK_STA_YMD_FROM).concat(SUFFIX_START));
			}

			// ＫＥＹ＿受付開始年月日（至）が設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_UK_STA_YMD_TO)) {
				sql_Buff4_1.append("     AND    KK0841.UK_STA_YMDHM <= ? ");

				// バインドリストの設定（ＫＥＹ＿受付開始年月日（至））
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_UK_STA_YMD_TO).concat(SUFFIX_END));
			}

			// ＫＥＹ＿受付終了年月日（自）が設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_UK_END_YMD_FROM)) {
				sql_Buff4_1.append("     AND    ? <= KK0841.UK_END_YMDHM ");

				// バインドリストの設定（ＫＥＹ＿受付終了年月日（自））
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_UK_END_YMD_FROM).concat(SUFFIX_START));
			}

			// ＫＥＹ＿受付終了年月日（至）が設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_UK_END_YMD_TO)) {
				sql_Buff4_1.append("     AND    KK0841.UK_END_YMDHM <= ? ");

				// バインドリストの設定（ＫＥＹ＿受付終了年月日（至））
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_UK_END_YMD_TO).concat(SUFFIX_END));
			}

			// ＫＥＹ＿割引適用契機コードが設定されている場合
			if (!inMsg.isNull(EKK0841B001CBSMsg.KEY_WRIB_APLY_OPTNTY_CD)) {
				sql_Buff4_1.append("     AND    KK0841.WRIB_APLY_OPTNTY_CD = ? ");

				// バインドリストの設定（ＫＥＹ＿割引適用契機コード）
				arrayParam.add(inMsg.getString(EKK0841B001CBSMsg.KEY_WRIB_APLY_OPTNTY_CD));
			}
			
			if ("2".equals( inMsg.getObject(EKK0841B001CBSMsg.FUNC_CODE).toString() ))
			{
				sql_Buff4_1.append("     AND    KK0841.WRIB_SCREEN_CTRL_CD = '1' ");
			}

			// SQL文_ORDER BY部
			// (5)
			StringBuffer sql_Buff5 = new StringBuffer();
			
			// ＫＥＹ＿ソート項目Ｎｏによってソート条件を結合する。
	 		// ソート区分判定
			String strSortKbn = null;
			if (SORT_ASC.equals(inMsg.getObject(EKK0841B001CBSMsg.KEY_SORT_KBN)))
			{
				// ＫＥＹ＿ソート区分が"1"(昇順)の場合
				strSortKbn = " ASC ";
			}
			else if (SORT_DESC.equals(inMsg.getObject(EKK0841B001CBSMsg.KEY_SORT_KBN)))
			{
				// ＫＥＹ＿ソート区分が"2"(降順)の場合
				strSortKbn = " DESC ";
			}
			else
			{
				strSortKbn = "";
			}
			
			// ソート項目判定
			sql_Buff5.append("ORDER BY " );
			if(SORT_DSP_CAMPAIGN_CD.equals(inMsg.getObject(EKK0841B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK0841.DSP_CAMPAIGN_CD ")
						.append(strSortKbn)
						.append(",");
			}
			else if(SORT_UK_STA_YMDHM.equals(inMsg.getObject(EKK0841B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK0841.UK_STA_YMDHM ")
						.append(strSortKbn)
						.append(",");
			}
			else if(SORT_UK_END_YMDHM.equals(inMsg.getObject(EKK0841B001CBSMsg.KEY_SORT_ITEM_NO)))
			{
				sql_Buff5.append("KK0841.UK_END_YMDHM ")
						.append(strSortKbn)
						.append(",");
			}
			
			sql_Buff5.append("KK0841.DSP_JUN ASC ");

			// SQL文の作成(検索条件フッタ)
			// (4-2)
			StringBuffer sql_Buff4_2 = new StringBuffer();
			sql_Buff4_2.append(" ) KK0841_01 ");

			// SQL文の作成(レコード集約フッタ)
			// (6-2)
			StringBuffer sql_Buff6_2 = new StringBuffer();
			sql_Buff6_2.append(" WHERE KK0841_01.LINE = 1 ")
						.append(" ) KK0841_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 iDataCnt = 0L;
			if (rsltQuery_Count.next())
			{
				iDataCnt = rsltQuery_Count.getLong("CNT");
			}

			// 表示件数
			Long iDispNum = inMsg.getStringAsLong(EKK0841B001CBSMsg.DISPLAY_NUM);

			// 表示ページ数
			Long iDispPage = inMsg.getStringAsLong(EKK0841B001CBSMsg.DISPLAY_PAGE_NUM);

			// 総ページ数
			String strMaxPage = JKKejbPagingUtil.calcTotalPage(iDataCnt, iDispNum);

			// 最大取得件数
			long lMaxNum = inMsg.getStringAsLong(EKK0841B001CBSMsg.MAX_SEARCH_NUM);

			// 共通部に値を設定する
			// 総検索件数
			inMsg.set(EKK0841B001CBSMsg.TOTAL_SEARCH_NUM, String.valueOf(iDataCnt));

			// 総ページ数
			inMsg.set(EKK0841B001CBSMsg.TOTAL_PAGE_NUM, strMaxPage);

			// データ取得件数が0件の場合エラー
			if (0L == iDataCnt)
			{
				inMsg.set(EKK0841B001CBSMsg.SEARCH_ERR_FLG, JPCModelConstant.SEARCH_ERR_FLG_ZERO);
				return;
			}

			// 最大取得件数を超えた場合エラー
			if (iDataCnt > lMaxNum)
			{
				inMsg.set(EKK0841B001CBSMsg.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[] iPages = JKKejbPagingUtil.calcSearchRows(iDispPage, iDispNum);
			long iRowSta = iPages[0];
			long iRowEnd = iPages[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, iRowSta);
			// パラメータの設定(検索終了行を指定)
			CAANJDBCUtil.setParam(pstmt_Page, ++iParamCntr, iRowEnd);

			// ResultSetの取得
			rsltQuery_Page = pstmt_Page.executeQuery();

			// EKK0841B001CBSMsgの明細にセットする項目
			String[] msgKeyList1 = {
					  EKK0841B001CBSMsg1List.DSP_CAMPAIGN_CD
					, EKK0841B001CBSMsg1List.WRIB_SVC_NM
					, EKK0841B001CBSMsg1List.UK_STA_YMDHM
					, EKK0841B001CBSMsg1List.UK_END_YMDHM
			};
			
			// 明細に処理結果(ResultSet)をマッピング
			CAANMsg[] outMsg1 = mapMessageList(rsltQuery_Page,msgKeyList1,"eo.ejb.cbs.cbsmsg.EKK0841B001CBSMsg1List",0);

			// 取得結果が0件の場合は表示ページ該当なしエラー
			if (0L == outMsg1.length)
			{
				inMsg.set(EKK0841B001CBSMsg.SEARCH_ERR_FLG, JPCModelConstant.SEARCH_ERR_FLG_NODATA);
				return;
			}

			// inMsg(CBSMsg)に明細をセット
			inMsg.set("EKK0841B001CBSMsg1List", outMsg1);

		} catch(SQLException e) {
			inMsg.set(EKK0841B001CBSMsg.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(EKK0841B001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}
}
