/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKChkShukkaChuKikiCC
*   ソースファイル名：JKKChkShukkaChuKikiCC.java
*   作成者          ：富士通
*   日付            ：2013年05月08日
*＜機能概要＞
*   出荷中機器チェックCCです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v4.00.00    2013/05/08   FJ）        新規作成(IT1-2013-0001177)
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKChkShukkaChuKikiConstCC;
import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.CCException;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.model.base.CAANMsg;

import eo.common.constant.JKKStrConst;
import eo.ejb.cbs.cbsmsg.EDK0011B080CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081A010CBSMsg1List;

/**
 * 出荷中機器チェックCCです。<p>
 * <br>
 * @author FJ
 */
public class JKKChkShukkaChuKikiCC extends AbstractCommonComponent
{
	/** エラーメッセージ */
	private static final String ERR_MSG = "INVALID_RETURN_MESSAGE";

	/** エラーメッセージ：パラメータ設定不正 */
	private static final String ERR_MSG_PARAM = "リクエストパラメータに誤りがあります。";

	/** サービスインタフェース呼び出しで使用するマッパー群 */
	private JKKChkShukkaChuKikiMapperCC mapper = null;

	/** SC呼び出し部品 */
	ServiceComponentRequestInvoker scCall = null;
	
	/** 配送ステータス（指示済） */
	private static final String HAISO_STAT_SJIZUMI = "002";

	/**
	 * 移動機器チェックの初期処理です。
	 * <br>
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @throws Throwable 
	 */
	private void init(IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// マッパーの初期化
		if (null == this.mapper)
		{
			this.mapper = new JKKChkShukkaChuKikiMapperCC();
		}

		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない。
		if (null == this.scCall)
		{
			this.scCall = new ServiceComponentRequestInvoker();
		}

		// ユーザ定義領域作成
		createUserData(param, fixedText);

		// リターンコードに正常を設定
		param.setControlMapData(SCControlMapKeys.RETURN_CODE, JCMConstants.RET_NORMAL);
	}

	/**
	 * 出荷中機器チェック処理を行います。<br>
	 * 指定されたサービス契約番号に紐付く機器に出荷中の機器が存在するかを判定します。<br>
	 * ｅｏモバイル（３Ｇ）、ｅｏモバイル（ＵＱ−ＷｉＭＡＸ）以外の場合は、チェック対象外とします。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable 
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite chkShukkaChuKiki(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// 初期処理
		init(param, fixedText);

		// リクエストパラメータの取得処理
		HashMap<String, Object> trgtData = (HashMap<String, Object>)param.getData(fixedText);

		// 出荷中機器有無に「無」を設定（初期値）
		trgtData.put(JKKChkShukkaChuKikiConstCC.SHUKKA_CHU_KIKI_UM, JKKStrConst.CD_DIV_UM_NASHI);

		// 入力パラメータチェック処理
		String errMsg = chkInput(handle, param, trgtData);
		if (null != errMsg && !errMsg.isEmpty())
		{
			// チェックエラー
			throw new CCException(errMsg, new Exception());
		}

		// サービス契約番号
		String svcKeiNo = (String)trgtData.get(JKKChkShukkaChuKikiConstCC.SVC_KEI_NO);

		// サービス契約一意照会
		CAANMsg[] msgEKK0081A010List = searchSvcKei(handle, param, fixedText, svcKeiNo);

		if (null == msgEKK0081A010List || msgEKK0081A010List.length == 0)
		{
			return param;
		}

		// 料金グループコード
		String prcGrpCd = msgEKK0081A010List[0].getString(EKK0081A010CBSMsg1List.PRC_GRP_CD);

		// チェック対象外サービスの判定
		if (!JKKStrConst.CD00133_08.equals(prcGrpCd) && !JKKStrConst.CD00133_09.equals(prcGrpCd))
		{
			return param;
		}

		// サービス契約に紐付く配送ステータスが指示済の配送情報取得
		// ※JKKBpCommon.searchHaisoInfoは、サービス契約に紐付く機器だけでなく、
		//   サービス契約回線内訳、サービス契約内訳に紐付く機器の配送も取得する仕様。
		//   現時点ではモバイルのみのチェックであるため、サービス契約に紐付く機器の配送が取得される前提で呼び出している
		ArrayList<String> haisoStatList = new ArrayList<String>();
		haisoStatList.add(HAISO_STAT_SJIZUMI);
		HashMap<String, Object> eDK0011B080Hash = new HashMap<String, Object>();
		JKKBpCommon.searchHaisoInfo(param, handle, svcKeiNo, null, null, null, haisoStatList, eDK0011B080Hash, fixedText);
		
		// 配送情報を取り出す
		CAANMsg[] eDK0011B080CBSMSG1list = (CAANMsg[])eDK0011B080Hash.get(EDK0011B080CBSMsg.EDK0011B080CBSMSG1LIST);
		
		// 取得できない場合、処理終了
		if (eDK0011B080CBSMSG1list == null || eDK0011B080CBSMSG1list.length == 0)
		{
			return param;
		}
		
		// 出荷中機器有無は「有」
		trgtData.put(JKKChkShukkaChuKikiConstCC.SHUKKA_CHU_KIKI_UM, JKKStrConst.CD_DIV_UM_ARI);
		
		return param;
	}

	/**
	 * 入力パラメータのチェックを行います。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param trgtData 対象データ
	 * @return エラーメッセージ
	 */
	@SuppressWarnings("unchecked")
	private String chkInput(SessionHandle handle, IRequestParameterReadWrite param, HashMap trgtData)
	{
		// 必須チェック
		String svcKeiNo = (String)trgtData.get(JKKChkShukkaChuKikiConstCC.SVC_KEI_NO);
		if (null == svcKeiNo || svcKeiNo.isEmpty())
		{
			return ERR_MSG_PARAM + "サービス契約番号が設定されていません。";
		}

		// チェックOK
		return "";
	}

	/**
	 * サービス契約一意照会サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param svcKeiNo サービス契約番号
	 * @return サービス契約一意照会結果
	 * @throws Throwable 例外が発生した場合
	 */
	private CAANMsg[] searchSvcKei(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, String svcKeiNo)
	throws Throwable
	{
		// 上りマッピング処理
		HashMap<String, Object> inMap = this.mapper.editInMsgEKK0081A010(param, svcKeiNo);
		// サービスインターフェース呼び出し
		CAANMsg rsltMsg = callSvcInter(handle, param, fixedText, inMap, new EKK0081A010CBSMsg().getContents());

		return rsltMsg.getCAANMsgList(EKK0081A010CBSMsg.EKK0081A010CBSMSG1LIST);
	}


	/*
	 * --------------------------------------------------------------------------------------------
	 *  以下共通で使用するUtil系のメソッド ↓↓↓↓↓
	 * --------------------------------------------------------------------------------------------
	 */

	/**
	 * サービスインターフェース呼び出し処理です。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param siInMap サービスインターフェースの入力マップ
	 * @param contents サービスインターフェースのテンプレート項目の配列
	 * @return 業務データ
	 * @throws Throwable 
	 */
	private CAANMsg callSvcInter(
			SessionHandle handle,
			IRequestParameterReadWrite param,
			String fixedText,
			HashMap<String, Object> siInMap,
			Object[][] contents)
			throws Throwable
	{
		
		// サービスインターフェースの呼び出し
		Map<?, ?> rsltMap = this.scCall.run(siInMap, handle);
		// エラーマッピング処理
		this.mapper.editResultRP(rsltMap, param, fixedText, contents);
		// エラーチェック処理
		errChk(rsltMap);
		// 業務データ取得処理
		CAANMsg workData = getWorkCAANMsg(rsltMap);

		return workData;
	}

	/**
	 * エラーチェック処理です。
	 * <br>
	 * @param msgList サービスインタフェース実行結果
	 * @throws SCCallException 
	 */
	private void errChk(
			Map<?, ?> msgList) 
			throws SCCallException
	{
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg template = templates[0];

		// リターンコード取得
		Integer returnCode = (Integer)msgList.get(JCMConstants.RET_CD_INT_KEY);
		
		// ステータス取得
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if ((0 != returnCode.intValue()) || (0 != templateStatus))
		{
			String errMsg = ERR_MSG;
			throw new SCCallException(errMsg, String.valueOf(returnCode), templateStatus);
		}
	}

	/**
	 * 業務データの取得処理です。
	 * <br>
	 * @param workMapKey 業務データのマップキー
	 * @param rslt SVIFの実行結果データ
	 * @return 業務データ
	 */
	private CAANMsg getWorkCAANMsg(Map<?, ?> rslt)
	{
		CAANMsg[] templates = (CAANMsg[])rslt.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg parentTemplate = templates[0];

		return parentTemplate;
	}

	/**
	 * ユーザ定義文字列がユーザ情報になければデータを作成します。 <br>
	 * 
	 * @param param 業務データ取得用I/F
	 * @param workMapKey 業務データのマップキー
	 * @return true：作成した　False：存在していたため作成不要
	 * @throws RequestParameterException
	 */
	private boolean createUserData(IRequestParameterReadWrite param, String workMapKey)
			throws RequestParameterException
	{
		if (param.getData(workMapKey) == null)
		{
			param.setData(workMapKey, new HashMap<String, Object>());
			return true;
		}

		return false;
	}
}
