/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JZMGetOrgPosCode
*   ソースファイル名：JZMGetOrgPosCode.java
*   作成者          ：富士通
*   日付            ：2012年03月15日
*＜機能概要＞
*   組織コードおよび立場コードを取得する部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00       2012/03/15   FJ) 宮前    新規作成
*   v3.00       2012/08/09   FJ) 宮前    【ST1-2012-0000282】統合認証連携 障害 対応
*   v32.00.00   2017/05/29   FJ) 河邊    【OM-2017-0000488】オープンカーソルエラー
*
**********************************************************************/
package eo.ejb.common;

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.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import eo.ejb.cbm.entity.ZM0131ETMsg;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg3List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg4List;

/**
 * 組織コードおよび立場コードを取得する部品です。
 * @author FJ
 *
 */
public class JZMGetOrgPosCode
{
	
	/** エラーメッセージ 立場コードの桁数エラー */
	private static final String ERR_MSG_POS_CD_LENGTH = "立場コードが4桁以外です。";

	/** KEY ワークグループ 立場コード */
	private static final String KEY_WKKBT_POSITION_CD = "WKKBT_POSITION_CD";
	
	/** KEY ワークグループ 組織コード */
	private static final String KEY_WKKBT_ORG_CD = "WKKBT_ORG_CD";
	
	/** KEY 上位組織コード */
	private static final String KEY_JOI_ORG_CD = "JOI_ORG_CD";
	
	/** KEY 立場コード */
	private static final String KEY_POSITION_CD = "POSITION_CD";
	
	/** KEY 組織コード */
	private static final String KEY_ORG_CD = "ORG_CD";
	
	/** KEY 権限適用組織種別コード */
	private static final String KEY_AUTHORITY_APLY_ORG_SBT_CD = "AUTHORITY_APLY_ORG_SBT_CD";
	
	/** KEY ユーザー名 */
	private static final String KEY_USER_NM = "USER_NM";
	
	/** パスワード有効期限 */
	private static final String PASS_LIMIT = "20991231";
	
	/** 基準日 パラメータセット用 */
	private static final int LOOP_MAX = 12;
	
	/** 権限適用組織種別コード 実組織 */
	private static final String ORG_SBT_CD = "01";
	
	/** 権限適用組織種別コード ワークグループ */
	private static final String WKGRP_SBT_CD = "02";
	
	/** 権限適用組織種別コード 中間組織 */
	private static final String CHUKAN_SBT_CD = "03";
	
	/** 権限適用組織種別コード 特別権限組織 */
	private static final String SPA_SBT_CD = "04";
	
	/** 認証結果 OK */
	private static final String NINSHO_OK = "0";
	
	/** 認証結果 NG */
	private static final String NINSHO_NG = "1";
	
	/** ブランク */
	private static final String BLANK = "";
	
	/** 初期パスワードフラグ 変更済み */
	private static final String SHOKI_PASS = "0";
	
	/**
	 * 組織コード立場コード取得処理<BR>
	 * 指定されたユーザーIDからそのユーザーが所属する組織および立場のコードを取得する。<BR>
	 * @param in_cbsmsg ユーザーIDがセットされたメッセージキャリアクラス
	 * @param inContext SQL文ログ出力用
	 * @return CAANMsg 組織コード、立場コードがセットされたキャリアクラス
	 * @throws Exception 
	 */
	public static CAANMsg getOrgPosCode(CAANMsg in_cbsmsg) throws Exception
	{
		
		// コネクション
		Connection con = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rs = null;
		
		// SQL文
		StringBuffer sql = new StringBuffer();
		
		//兼務情報明細
		ArrayList<CAANMsg> orgList = new ArrayList<CAANMsg>();
		
		//ワークグループ
		ArrayList<CAANMsg> wkList = new ArrayList<CAANMsg>();
		
		//中間組織
		ArrayList<CAANMsg> chList = new ArrayList<CAANMsg>();
		
		//特別権限組織
		ArrayList<CAANMsg> spList = new ArrayList<CAANMsg>();
		
		// 所属コード（主務）取得フラグ true:取得済み false:未取得
		boolean flgShumu = false;
		
		boolean isGetRec = false;
		
		// (1) パラメータチェック処理
		if(in_cbsmsg == null)
		{
			
			//引数の指定がない。
			return null;
		}
		
		//ユーザーID
		String user_id = in_cbsmsg.getString(ECCTGN00001CBSMsg.USER_ID);
		if(user_id == null || BLANK.equals(user_id))
		{
			
			//ユーザーIDの指定がない。
			return null;
		}
		try
		{
		
			// (2) コネクション取得
			con = JSYejbConnection.getConnection(ZM0131ETMsg.getTableName());
		
			// (3) SQL文組み立て
			sql = getSqlForSelectOrgPosCode();
		
			// (4) SQL文実行
			//  (a) PreparedStatementの設定
			pstmt = con.prepareStatement(sql.toString());
			
			//基準年月日
			String std_date = JPCModelCommon.getSysDate();
			for(int iCnt = 1; iCnt <= LOOP_MAX; iCnt++)
			{
				CAANJDBCUtil.setParam(pstmt, iCnt, std_date);
			}
			
			//ユーザーID
			CAANJDBCUtil.setParam(pstmt, LOOP_MAX + 1, user_id);
		
			//  (c) ResultSetの取得
			rs = pstmt.executeQuery();
		
			// (5) 結果取得
			while(rs.next())
			{
		
				//  ・ 取得した結果が1件以上の場合、以下のとおりCAANMsgをセットする。
				if(!isGetRec)
				{
					
					// 認証結果
					in_cbsmsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_OK);
					
					// 初期パスワードフラグ
					in_cbsmsg.set(ECCTGN00001CBSMsg.SHK_PASSWORD_FLG, SHOKI_PASS);
					
					// パスワード有効期限
					in_cbsmsg.set(ECCTGN00001CBSMsg.PASSWORD_YK_KIGEN, PASS_LIMIT);
					
					// 従業員管理区分CD
//					in_cbsmsg.set(ECCTGN00001CBSMsg.WORKER_KANRI_DIV_CD, BLANK);
					
					// 漢字氏名（姓）
					in_cbsmsg.set(ECCTGN00001CBSMsg.KANJI_NM_FMLNM, rs.getString(KEY_USER_NM));
					
					// 漢字氏名（名）
					in_cbsmsg.set(ECCTGN00001CBSMsg.KANJI_NM_FSTNM, BLANK);
					isGetRec = true;
				}
				
				// 権限適用組織種別コード
				String sbt_cd = rs.getString(KEY_AUTHORITY_APLY_ORG_SBT_CD);
				
				if(ORG_SBT_CD.equals(sbt_cd))
				{
					
					String pos_cd = rs.getString(KEY_POSITION_CD);
					// 職位コード
					String shoku_cd = getShokui_cd(pos_cd);
					
					// 従業員管理区分CD
					String kanri_kbn = getKanri_kbn(pos_cd);
					
					// はじめに登場した実組織を主務とする。
					if(!flgShumu)
					{
						
						// 所属コード
						in_cbsmsg.set(ECCTGN00001CBSMsg.SYOZK_CD, rs.getString(KEY_ORG_CD));
						
						// 職位コード
						in_cbsmsg.set(ECCTGN00001CBSMsg.SYOKUI_CD, shoku_cd);
						
						// 従業員管理区分CD
						in_cbsmsg.set(ECCTGN00001CBSMsg.WORKER_KANRI_DIV_CD, kanri_kbn);
						
						flgShumu = true;
					}
					else
					{
						
						// 兼務情報明細
						CAANMsg orgMsg = new CAANMsg(ECCTGN00001CBSMsg1List.class.getName());
						
						//   兼務所属コード
						orgMsg.set(ECCTGN00001CBSMsg1List.KENMU_SYOZK_CD, rs.getString(KEY_ORG_CD));
						
						// 主務の従業員管理区分CD取得
						String shu_kanri_kbn = in_cbsmsg.getString(ECCTGN00001CBSMsg.WORKER_KANRI_DIV_CD);
						
						if(!shu_kanri_kbn.equals(kanri_kbn))
						{
							throw new Exception("従業員管理区分CDが異なります。立場コード：" + pos_cd);
						}
						
						//   兼務職位コード
						orgMsg.set(ECCTGN00001CBSMsg1List.KENMU_SYOKUI_CD, shoku_cd);
						orgList.add(orgMsg);
					}
				}
				else if(WKGRP_SBT_CD.equals(sbt_cd))
				{
					
					//ワークグループ組織コード・立場コード明細
					CAANMsg wkMsg = new CAANMsg(ECCTGN00001CBSMsg2List.class.getName());
					
					//  ワークグループ上位組織コード
					wkMsg.set(ECCTGN00001CBSMsg2List.WKGRP_JOI_ORG_CD, rs.getString(KEY_JOI_ORG_CD));
					
					//  ワークグループ組織コード
					wkMsg.set(ECCTGN00001CBSMsg2List.WKGRP_ORG_CD, rs.getString(KEY_WKKBT_ORG_CD));
					
					//  ワークグループ立場コード
					wkMsg.set(ECCTGN00001CBSMsg2List.WKGRP_POSITION_CD, rs.getString(KEY_WKKBT_POSITION_CD));
					wkList.add(wkMsg);
				}
				else if(CHUKAN_SBT_CD.equals(sbt_cd))
				{
					
					//中間組織コード・立場コード明細
					CAANMsg chMsg = new CAANMsg(ECCTGN00001CBSMsg3List.class.getName());
					
					//  中間上位組織コード
					chMsg.set(ECCTGN00001CBSMsg3List.CHUKAN_JOI_ORG_CD, rs.getString(KEY_JOI_ORG_CD));
					
					//  中間組織コード
					chMsg.set(ECCTGN00001CBSMsg3List.CHUKAN_ORG_CD, rs.getString(KEY_WKKBT_ORG_CD));
					
					//  中間立場コード
					chMsg.set(ECCTGN00001CBSMsg3List.CHUKAN_POSITION_CD, rs.getString(KEY_WKKBT_POSITION_CD));
					chList.add(chMsg);
				}
				else if(SPA_SBT_CD.equals(sbt_cd))
				{
					
					//  特別権限組織コード・立場コード明細
					CAANMsg spMsg = new CAANMsg(ECCTGN00001CBSMsg4List.class.getName());
					
					//  特別権限組織コード
					spMsg.set(ECCTGN00001CBSMsg4List.SPCL_ORG_CD, rs.getString(KEY_WKKBT_ORG_CD));
					
					//  特別権限立場コード
					spMsg.set(ECCTGN00001CBSMsg4List.SPCL_POSITION_CD, rs.getString(KEY_WKKBT_POSITION_CD));
					spList.add(spMsg);
				}
			}
		
			//  ・ 取得した結果が0件の場合、認証NGとして処理を終了する。
			if(!isGetRec)
			{
				
				// 認証結果
				in_cbsmsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_NG);
				
				// 初期パスワードフラグ
				in_cbsmsg.set(ECCTGN00001CBSMsg.SHK_PASSWORD_FLG, BLANK);
				
				// パスワード有効期限
				in_cbsmsg.set(ECCTGN00001CBSMsg.PASSWORD_YK_KIGEN, BLANK);
				
				// 従業員管理区分CD
				in_cbsmsg.set(ECCTGN00001CBSMsg.WORKER_KANRI_DIV_CD, BLANK);
			}
			else
			{
				
				//兼務情報明細
				CAANMsg[] orgListToArray = (CAANMsg[])orgList.toArray(new CAANMsg[0]);
				in_cbsmsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG1LIST, orgListToArray);
				
				//ワークグループ
				CAANMsg[] wkListToArray = (CAANMsg[])wkList.toArray(new CAANMsg[0]);
				in_cbsmsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG2LIST, wkListToArray);
				
				//中間組織
				CAANMsg[] chListToArray = (CAANMsg[])chList.toArray(new CAANMsg[0]);
				in_cbsmsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG3LIST, chListToArray);
				
				//特別権限組織
				CAANMsg[] spListToArray = (CAANMsg[])spList.toArray(new CAANMsg[0]);
				in_cbsmsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG4LIST, spListToArray);
				
			}
		}
		catch(SQLException sqlExp)
		{
			in_cbsmsg.set(ECCTGN00001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw sqlExp;
		}
		finally
		{
		
			// (6) 終了処理
			try
			{
				if(rs != null)
				{
					rs.close();
				}
				if(pstmt != null)
				{
					pstmt.close();
				}
// OM-2017-0000488 2017/05/29 ADD START
				if (con != null)
				{
					CAANConnectionMgr.getInstance().close(con);
				}
// OM-2017-0000488 2017/05/29 ADD END
			}
			catch(SQLException sqlExp)
			{
				in_cbsmsg.set(ECCTGN00001CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw sqlExp;
			}
		}
		return in_cbsmsg;
	}
	
	/**
	 * ユーザーIDからそのユーザーが所属する組織コードおよび立場コードを取得するSQL文を作成します。
	 * @return StringBuffer 作成したSQL文
	 */
	private static StringBuffer getSqlForSelectOrgPosCode()
	{
		StringBuffer sql = new StringBuffer();
		
		sql.append("SELECT ")
			.append(" ZM0051.USER_NM USER_NM, ")
			.append(" ZM0051.SHUMU_SHOZK_ORG_CD SHUMU_SHOZK_ORG_CD, ")
			.append(" ZM0051.SHUMU_SHOZK_POSITION_CD SHUMU_SHOZK_POSITION_CD, ")
			.append(" ZM0041.ORG_CD ORG_CD, ")
			.append(" ZM0041.POSITION_CD POSITION_CD, ")
			.append(" ZM0151.ORG_CD JOI_ORG_CD, ")
			.append(" ZM0041.WKKBT_ORG_CD WKKBT_ORG_CD, ")
			.append(" ZM0041.WKKBT_POSITION_CD WKKBT_POSITION_CD, ")
			.append(" ZM0041.AUTHORITY_APLY_ORG_SBT_CD AUTHORITY_APLY_ORG_SBT_CD ")
			.append("FROM ")
			.append(" ZM_M_USER ZM0051 INNER JOIN ZM_M_USER_HTG_KGGRP ZM0131 ")
			.append(" ON(")
			.append("    ZM0051.USER_ID = ZM0131.USER_ID ")
			.append("    AND ZM0051.USER_TSTAYMD <= ? AND ZM0051.USER_TENDYMD >= ?")
			.append(" )")
			.append(" INNER JOIN ZM_M_AUTHORITY_GRP ZM0041 ")
			.append(" ON(")
			.append("    ZM0131.KGGRP_CD = ZM0041.KGGRP_CD ")
			.append("    AND ZM0041.AUTHORITY_GRP_TSTAYMD <= ? AND ZM0041.AUTHORITY_GRP_TENDYMD >= ?")
			.append(" )")
			.append(" LEFT OUTER JOIN ZM_M_WKKBT_ORG ZM0151 ")
			.append(" ON(")
			.append("    ZM0041.WKKBT_ORG_CD = ZM0151.WKKBT_ORG_CD ")
			.append("    AND ZM0151.WKKBT_ORG_TSTAYMD <= ? AND ZM0151.WKKBT_ORG_TENDYMD >= ?")
			.append(" )")
			.append(" LEFT OUTER JOIN ZM_M_ORGANIZATION ZM0061 ")
			.append(" ON(")
			.append("    ZM0041.ORG_CD = ZM0061.ORG_CD ")
			.append("    AND ZM0061.ORG_TSTAYMD <= ? AND ZM0061.ORG_TENDYMD >= ?")
			.append(" )")
			.append(" LEFT OUTER JOIN ZM_M_POSITION ZM0071 ")
			.append(" ON(")
			.append("    ZM0041.POSITION_CD = ZM0071.POSITION_CD ")
			.append("    AND ZM0071.POSITION_TSTAYMD <= ? AND ZM0071.POSITION_TENDYMD >= ?")
			.append(" )")
			.append(" LEFT OUTER JOIN ZM_M_WKKBT_POSITION ZM0231 ")
			.append(" ON(")
			.append("    ZM0041.WKKBT_POSITION_CD = ZM0231.WKKBT_POSITION_CD")
			.append("    AND ZM0231.WKKBT_POSITION_TSTAYMD <= ? AND ZM0231.WKKBT_POSITION_TENDYMD >= ?")
			.append(" )")
			.append("WHERE")
			.append(" ZM0051.USER_ID = ?")
			.append("ORDER BY ")
			.append(" ZM0041.AUTHORITY_APLY_ORG_SBT_CD,")
			.append(" ZM0041.ORG_CD,")
			.append(" ZM0041.POSITION_CD,")
			.append(" ZM0041.WKKBT_ORG_CD,")
			.append(" ZM0041.WKKBT_POSITION_CD");
		return sql;
	}

	/**
	 * 立場コードから職位コードを取得
	 * @param pos_cd 立場コード
	 * @return String 職位コード
	 * @throws Exception
	 */
	private static String getShokui_cd(String pos_cd) throws Exception
	{
		String retValue = null;
		
		if(pos_cd.length() == 4)
		{
			
			// 職位コード
			retValue = pos_cd.substring(2);
		}
		else
		{
			throw new Exception(ERR_MSG_POS_CD_LENGTH);
		}
		
		
		return retValue;
	}
	
	/**
	 * 立場コードから従業員管理区分を取得
	 * @param pos_cd 立場コード
	 * @return String 従業員管理区分
	 * @throws Exception
	 */
	private static String getKanri_kbn(String pos_cd) throws Exception
	{
		String retValue = null;
		
		if(pos_cd.length() == 4)
		{
			
			// 従業員管理区分
			retValue = pos_cd.substring(0, 2);
		}
		else
		{
			throw new Exception(ERR_MSG_POS_CD_LENGTH);
		}
		
		
		return retValue;
		
	}
}
