/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbKK0201NumberParts
*	ソースファイル名：JKKejbKK0201NumberParts.java
*	作成者			：富士通
*	日付			：2012年09月27日
*＜機能概要＞
*	サービス契約内訳<eoモバイル>採番部品クラス
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/09/27	富士通		新規作成
*
**********************************************************************/

package eo.ejb.common.edit;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

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.JSYejbSucceedDataAccess;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0121ETMsg;
import eo.ejb.cbm.entity.KK0161ETMsg;
import eo.ejb.cbm.entity.KK0201ETMsg;
import eo.ejb.cbm.entity.KK0341ETMsg;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0121DBABase;
import eo.ejb.common.db.JKKejbKK0161DBABase;
import eo.ejb.common.db.JKKejbKK0201DBABase;
import eo.ejb.common.db.JKKejbZM0321DBAccess;

/**
 * <p>
 * サービス契約内訳<eoモバイル>採番部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbKK0201NumberParts extends JKKejbNumberPartsBase
{

	/** サービス契約内訳<eoモバイル>シーケンス名（UQ認証IDパスワード） */
	public static final String SEQ_UQ_NINSHO_ID_PWD = "SEQ_UQ_NINSHO_ID_PWD";

	/** 桁数(UQ認証IDパスワード) */
	public static final int SEQ_UQ_NINSHO_ID_PWD_LENGTH = 10;

	/** 乱数(UQ認証PASS) */
	public static final int RANDOM_LENGTH = 10;

	/** 乱数(UQ認証PASS.eoADSL) */
	public static final int RANDOM_LENGTH_ADSL = 8;

	/** 接頭語(N) */
	public static final String PREFIX_N = "N";

	/** 接頭語(A) */
	public static final String PREFIX_A = "A";

	/** 接頭語(S) */
	public static final String PREFIX_S = "S";

	/** 引継ぎデータアクセスキー（UQ認証IDパスワード） */
	private static final String UQ_NINSYO_PWD = "UQNINSHOIDPWD";
	
	/** 業務パラメータ（UQ事業者ID） */
	private static final String WORK_PARAM_UQ_JIGYOSHA_CD = "KK_UQ_JIGYOSHA_CD";

	/** 変換表Ａ */
	private static final HashMap<String, String> CHANGE_LIST_A = new HashMap<String, String>();

	static
	{
		// 変換配列設定
		CHANGE_LIST_A.put("0", "kmnpqrstuv");
		CHANGE_LIST_A.put("1", "pqrstuvwxy");
		CHANGE_LIST_A.put("2", "tuvwxyzabc");
		CHANGE_LIST_A.put("3", "ijkmnpqrst");
		CHANGE_LIST_A.put("4", "cdefghijkm");
		CHANGE_LIST_A.put("5", "mnpqrstuvw");
		CHANGE_LIST_A.put("6", "abcdefghij");
		CHANGE_LIST_A.put("7", "stuvwxyzab");
		CHANGE_LIST_A.put("8", "hijkmnpqrs");
		CHANGE_LIST_A.put("9", "npqrstuvwx");
	}

	/**
	 * コンストラクタです。
	 */
	public JKKejbKK0201NumberParts()
	{
	}
	
	/**
	 * <p>
	 * サービス契約のカレント検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo サービス契約番号
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0081(CAANMsg inCBSMsg, String svcKeiNo)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		// サービス契約のカレント検索を行う
		return new JKKejbKK0081DBABase().findByCurrent(inETMsg);
	}
	
	/**
	 * <p>
	 * サービス契約内訳のカレント検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiUcwkNo サービス契約内訳番号
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0161(CAANMsg inCBSMsg, String svcKeiUcwkNo)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0161ETMsg.class.getName());
		inETMsg.set(KK0161ETMsg.SVC_KEI_UCWK_NO, svcKeiUcwkNo);
		inETMsg.set(KK0161ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		// サービス契約内訳のカレント検索を行う
		return new JKKejbKK0161DBABase().findByCurrent(inETMsg);
	}
	
	/**
	 * <p>
	 * サービス契約内訳<eoモバイル>のサブタイプ検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiUcwkNo サービス契約内訳番号
	 * @param geneAddDtm 世代登録年月日時分秒
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0201(CAANMsg inCBSMsg, String svcKeiUcwkNo, String geneAddDtm)
	{
		// サブタイプ検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0201ETMsg.class.getName());
		inETMsg.set(KK0201ETMsg.SVC_KEI_UCWK_NO, svcKeiUcwkNo);
		inETMsg.set(KK0201ETMsg.GENE_ADD_DTM, geneAddDtm);

		// サービス契約内訳<eoモバイル>のサブタイプ検索を行う
		return new JKKejbKK0201DBABase().findByPrimaryKey(inETMsg);
	}
	
	/**
	 * <p>
	 * サービス契約<eoモバイル>のサブタイプ検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo サービス契約番号
	 * @param geneAddDtm 世代登録年月日時分秒
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0121(CAANMsg inCBSMsg, String svcKeiNo, String geneAddDtm)
	{
		// サブタイプ検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0121ETMsg.class.getName());
		inETMsg.set(KK0121ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0121ETMsg.GENE_ADD_DTM, geneAddDtm);

		// サービス契約内訳<eoモバイル>のサブタイプ検索を行う
		return new JKKejbKK0121DBABase().findByPrimaryKey(inETMsg);
	}
	
	/**
	 * <p>
	 * サービス契約内訳<eoモバイル>-UQ認証ID編集処理を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inSvcKeiUcwkNo サービス契約内訳番号
	 * @return 編集されたサービス契約内訳<eoモバイル>のUQ認証ID
	 */
	public Object getUqNinshoIdEdit(CAANMsg inMsg, AgentDispatchContext inContext, Object inSvcKeiUcwkNo)
	{
		
		// 機能コードのチェック（チェックモードの場合は採番しない）
		if (isFuncMode(inMsg))
		{
			return null;
		}
		
		String value = null;
		String svcKeiNo = null;
		
		// 対象のサービス内訳契約番号でカレント検索を行う
		CAANMsg ret0161 = getCurrentKK0161(inMsg, inSvcKeiUcwkNo.toString());
		
		// サービス内訳契約が存在しない場合
		if (null == ret0161)
		{
			return null;
		}
		
		// 対象のサービス契約内訳<eoモバイル>のサブタイプ検索を行う
		CAANMsg ret0201 = getCurrentKK0201(inMsg, inSvcKeiUcwkNo.toString(), ret0161.getString(KK0161ETMsg.GENE_ADD_DTM));
		
		// サービス内訳契約<eoモバイル>が存在しない場合
		if (null == ret0201)
		{
			return null;
		}
		
		//　UQ認証IDが設定されている場合はカレント引継ぎ
		if (!ret0201.isNull(KK0201ETMsg.UQ_NINSHO_ID))
		{
			value = ret0201.getString(KK0201ETMsg.UQ_NINSHO_ID);
			return value;
		}
		
		//　サービス契約内訳の料金コースが「A46」以外の場合は何もしない
		if (!"A46".equals(ret0161.getString(KK0161ETMsg.PCRS_CD)))
		{
			return null;
		}
		
		svcKeiNo = ret0161.getString(KK0161ETMsg.SVC_KEI_NO);
		
		// 対象のサービス契約番号でサービス契約のカレント検索を行う
		CAANMsg ret0081 = getCurrentKK0081(inMsg, svcKeiNo.toString());
		
		// サービス内訳契約が存在しない場合
		if (null == ret0081)
		{
			return null;
		}
		
		//　サービス契約の料金コースが「A28」「A29」以外の場合は何もしない
		if (!("A28".equals(ret0081.getString(KK0081ETMsg.PCRS_CD)) ||
				"A29".equals(ret0081.getString(KK0081ETMsg.PCRS_CD))))
		{
			return null;
		}
		
		//　サービス契約の料金コースが「A28」の場合
		if ("A28".equals(ret0081.getString(KK0081ETMsg.PCRS_CD)))
		{
			//　機器提供サービス契約のチェックを行う
			if (!chkKktkSvcKei(inMsg, inContext, svcKeiNo))
			{
				return null;
			}
		}
		
		// 対象のサービス契約<eoモバイル>のサブタイプ検索を行う
		CAANMsg ret0121 = getCurrentKK0121(inMsg, svcKeiNo, ret0081.getString(KK0081ETMsg.GENE_ADD_DTM));
		
		// サービス契約<eoモバイル>が存在しない場合
		if (null == ret0121)
		{
			return null;
		}
		
		//UQ認証IDの払出を行う
		value = getuqNinshoId(ret0121.getString(KK0121ETMsg.MACAD));
		
		return value;
	}
	
	/**
	 * <p>
	 * サービス契約内訳<eoモバイル>-UQ認証IDパスワード編集処理を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inSvcKeiUcwkNo サービス契約内訳番号
	 * @return 編集されたサービス契約内訳<eoモバイル>のUQ認証IDパスワード
	 */
	public Object getUqNinshoIdPwdEdit(CAANMsg inMsg, AgentDispatchContext inContext, Object inSvcKeiUcwkNo)
	{
		
		// 機能コードのチェック（チェックモードの場合は採番しない）
		if (isFuncMode(inMsg))
		{
			return null;
		}
		
		Object value = null;
		String svcKeiNo = null;
		
		// 対象のサービス内訳契約番号でカレント検索を行う
		CAANMsg ret0161 = getCurrentKK0161(inMsg, inSvcKeiUcwkNo.toString());
		
		// サービス内訳契約が存在しない場合
		if (null == ret0161)
		{
			return null;
		}
		
		// 対象のサービス契約内訳<eoモバイル>のサブタイプ検索を行う
		CAANMsg ret0201 = getCurrentKK0201(inMsg, inSvcKeiUcwkNo.toString(), ret0161.getString(KK0161ETMsg.GENE_ADD_DTM));
		
		// サービス内訳契約が存在しない場合
		if (null == ret0201)
		{
			return null;
		}
		
		//　UQ認証IDパスワードが設定されている場合はカレント引継ぎ
		if (!ret0201.isNull(KK0201ETMsg.UQ_NINSHO_ID_PWD))
		{
			value = ret0201.getString(KK0201ETMsg.UQ_NINSHO_ID_PWD);
			return value;
		}
		
		//　サービス契約内訳の料金コースが「A46」以外の場合は何もしない
		if (!"A46".equals(ret0161.getString(KK0161ETMsg.PCRS_CD)))
		{
			return null;
		}
		
		svcKeiNo = ret0161.getString(KK0161ETMsg.SVC_KEI_NO);
		
		// 対象のサービス契約番号でサービス契約のカレント検索を行う
		CAANMsg ret0081 = getCurrentKK0081(inMsg, svcKeiNo.toString());
		
		// サービス内訳契約が存在しない場合
		if (null == ret0081)
		{
			return null;
		}
		
		//　サービス契約の料金コースが「A28」「A29」以外の場合は何もしない
		if (!("A28".equals(ret0081.getString(KK0081ETMsg.PCRS_CD)) ||
				"A29".equals(ret0081.getString(KK0081ETMsg.PCRS_CD))))
		{
			return null;
		}
		
		//　サービス契約の料金コースが「A28」の場合
		if ("A28".equals(ret0081.getString(KK0081ETMsg.PCRS_CD)))
		{
			//　機器提供サービス契約のチェックを行う
			if (!chkKktkSvcKei(inMsg, inContext, svcKeiNo))
			{
				return null;
			}
		}
		
		//UQ認証IDパスワードの払出を行う
		value = getUqNinshoIdPwd(inMsg, inContext);
		
		return value;
	}

	/**
	 * <p>
	 * 機器提供サービス契約のチェックを行います。
	 * </p>
	 * @param inMsg	 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param svcKeiNo サービス契約番号
	 * @return 機器提供サービス契約が存在する場合はtrue。存在しない場合はfalse。
	 */
	public boolean chkKktkSvcKei(CAANMsg inMsg, AgentDispatchContext inContext, String svcKeiNo)
	{
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;

		long lDataCnt = 0L;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(KK0341ETMsg.getTableName());

			// SQL文
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ");
			sql_Buff.append("     COUNT(*) AS CNT ");
			sql_Buff.append(" FROM ");
			sql_Buff.append("     KK_T_KKTK_SVC_KEI KK0341 ");
			sql_Buff.append(" WHERE ");
			sql_Buff.append("     KK0341.SVC_KEI_NO = ? ");
			sql_Buff.append("     AND KK0341.TAKNKIKI_SBT_CD = 'J0' ");
			sql_Buff.append("     AND KK0341.KKTK_SBT_CD = '03' ");
			sql_Buff.append("     AND (KK0341.KKTK_SVC_KEI_NO, KK0341.RSV_APLY_YMD || KK0341.GENE_ADD_DTM) = ");
			sql_Buff.append("         (SELECT KK0341_GENE.KKTK_SVC_KEI_NO, MAX(KK0341_GENE.RSV_APLY_YMD || KK0341_GENE.GENE_ADD_DTM) AS KK0341_MAX ");
			sql_Buff.append("          FROM   KK_T_KKTK_SVC_KEI KK0341_GENE ");
			sql_Buff.append("          WHERE  KK0341_GENE.KKTK_SVC_KEI_NO = KK0341.KKTK_SVC_KEI_NO ");
			sql_Buff.append("          AND    KK0341_GENE.RSV_APLY_YMD <= ? ");
			sql_Buff.append("          AND    KK0341_GENE.RSV_APLY_CD = '2' ");
			sql_Buff.append("          AND    KK0341_GENE.MK_FLG= '0' ");
			sql_Buff.append("          GROUP BY KK0341_GENE.KKTK_SVC_KEI_NO) ");

			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);

			// パラメータの設定(サービス契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, 1, svcKeiNo);
			// パラメータの設定(運用日付を指定)
			CAANJDBCUtil.setParam(pstmt, 2, JKKModelCommon.getOpeDate(inMsg));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// 件数を返却する
			if (rsltQuery.next())
			{
				lDataCnt = rsltQuery.getLong("CNT");
			}

			// 対象データが存在する場合はtrueを返却する
			if (lDataCnt > 0)
			{
				return true;
			}

		}
		catch(SQLException se)
		{
			throw new CAANRuntimeException(se);
		}
		finally
		{
			// 資源の解放
			try
			{
				if(rsltQuery != null)
				{
					rsltQuery.close();
				}
				if(pstmt != null)
				{
					pstmt.close();
				}
				if(con1 != null)
				{
					CAANConnectionMgr.getInstance().close((java.sql.Connection)con1);
				}
			}
			catch(SQLException se)
			{
				throw new CAANRuntimeException(se);
			}
		}
		return false;
	}

	/**
	 * UQ認証ID取得処理
	 * @param macad MACアドレス
	 * @return UQ認証ID
	 */
	private String getuqNinshoId(String macad)
	{
		// 業務パラメータより取得
		JKKejbZM0321DBAccess wkParamDba = new JKKejbZM0321DBAccess();
		return wkParamDba.getParamE(WORK_PARAM_UQ_JIGYOSHA_CD).concat(macad).concat(JKKModelCommon.getSysDateTime());
	}
	
	/**
	 * <p>
	 * サービス契約内訳<eoモバイル>-UQ認証IDパスワードの採番処理を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 採番されたサービス契約<eoモバイル>のUQ認証IDパスワード
	 */
	public Object getUqNinshoIdPwd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		String value = null;

		// 機能コードのチェック（チェックモードの場合は採番しない）
		if (isFuncMode(inMsg))
		{
			return null;
		}

		// 引継データの取得
		value = (String)JSYejbSucceedDataAccess.getSucceedData(UQ_NINSYO_PWD);

		// 取得結果がnullの場合、パスワードを生成
		if (value == null)
		{
			// モデル共通アクセッサー部品・Oracleシーケンス取得処理
			Long seq = Long.parseLong(JCCModelCommon.getFormatedNextSeq(SEQ_UQ_NINSHO_ID_PWD, "", SEQ_UQ_NINSHO_ID_PWD_LENGTH));

			// シード値を使用して乱数を発生
			String random = getRandomNumberSeed(RANDOM_LENGTH, seq);

			// 変換処理
			StringBuffer pwd = new StringBuffer();

			// (1)乱数の9桁目,10桁目を元に変換表Ａ変換処理を呼び出す
			pwd.append(toAlphabetA(random.substring(8, 9), random.substring(9, 10)));
			// (2)乱数の1桁目,10桁目の加算値の下1桁目を設定する
			pwd.append(toNumLastDigit(random.substring(0, 1), random.substring(9, 10)));
			// (3)乱数の3桁目,4桁目を元に変換表Ａ変換処理を呼び出す
			pwd.append(toAlphabetA(random.substring(2, 3), random.substring(3, 4)));
			// (4)乱数の9桁目を設定する
			pwd.append(random.substring(8, 9));
			// (5)乱数の8桁目を設定する
			pwd.append(random.substring(7, 8));
			// (6)乱数の5桁目,6桁目を元に変換表Ａ変換処理を呼び出す
			pwd.append(toAlphabetA(random.substring(4, 5), random.substring(5, 6)));
			// (7)乱数の2桁目,4桁目の加算値の下1桁目を設定する
			pwd.append(toNumLastDigit(random.substring(1, 2), random.substring(3, 4)));
			// (8)乱数の7桁目,8桁目を元に変換表Ａ変換処理を呼び出す
			pwd.append(toAlphabetA(random.substring(6, 7), random.substring(7, 8)));

			value = pwd.toString();

			// 引継データの設定
			JSYejbSucceedDataAccess.setSucceedData(UQ_NINSYO_PWD, value);
		}

		// 結果を返却
		return value;
	}

	/**
	 * <p>
	 * 変換表Ａを使用して英字変換を行います。
	 * </p>
	 * @param str1 変換元データの１桁目
	 * @param str2 変換元データの２桁目
	 * @return 変換した英字。
	 */
	private String toAlphabetA(String str1, String str2)
	{
		// 変換表Ａを使用して英字変換を行う
		return toAlphabetTarget(str1, str2, CHANGE_LIST_A);
	}
}
