/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKAgntUpdCC
*   ソースファイル名：JKKAgntUpdCC.java
*   作成者          ：富士通
*   日付            ：2012年09月08日
*＜機能概要＞
*   代理店更新CCです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v4.00.00    2012/09/08   FJ）        新規作成
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.HashMap;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
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.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.JPCModelConstant;
import eo.common.util.JPCDateChecker;
import eo.ejb.cbs.cbsmsg.EKK0061C010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0061C020CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0061D010CBSMsg;

/**
 * 代理店更新CCです。<p>
 * <br>
 * @author FJ
 */
public class JKKAgntUpdCC extends AbstractCommonComponent
{
	/** エラーメッセージ ：INVALID_RETURN_MESSAGE */
	public static final String ERR_MSG_INVALID_RET_MSG = "INVALID_RETURN_MESSAGE";

	/** 更新パターン：適用中 */
	private static final int UPD_PTN_APLY = 1;

	/** 更新パターン：予約（適用開始後） */
	private static final int UPD_PTN_RSV_TSTA_AF = 2;

	/** 更新パターン：予約（適用開始前） */
	private static final int UPD_PTN_RSV_TSTA_BF = 3;

	/** サービスインタフェース呼び出しで使用するマッパー群 */
	private JKKAgntUpdMapperCC mapper = new JKKAgntUpdMapperCC();
	
	/** SC呼び出し部品 */
	ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

	/**
	 * 代理店更新処理を行います。<br>
	 * 
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite updAgnt(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
			throws Throwable
	{
		HashMap<String, Object> userData = (HashMap<String, Object>)param.getData(fixedText);

		// 更新パターンを判定
		int updPtn = Integer.valueOf((String)userData.get("upd_ptn"));

		// 適用中情報の更新
		if (UPD_PTN_APLY == updPtn)
		{
			// 代理店変更
			updAgnt(handle, param, fixedText, userData);
		}
		// 予約情報の更新
		else
		{
			// 代理店予約取消
			String upd_dtm = delRsvAgnt(handle, param, fixedText, userData);
			// チェックモードの場合、代理店予約取消が実行されず、代理店変更の予約情報存在チェックエラー、
			// または代理店登録の代理店存在チェックエラーになるため、代理店変更を実行しない
			String func_code = (String)userData.get("func_code");
			if (JPCModelConstant.FUNC_CD_2.equals(func_code))
			{
				return param;
			}
			if (UPD_PTN_RSV_TSTA_AF == updPtn)
			{
				// 代理店変更
				userData.put("upd_dtm_bf", upd_dtm);
				updAgnt(handle, param, fixedText, userData);
			}
			else
			{
				// 代理店登録
				addAgnt(handle, param, fixedText, userData);
			}
		}

		return param;
	}

	/**
	 * 代理店登録サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param userData ユーザデータ
	 * @throws Throwable 例外が発生した場合
	 */
	private void addAgnt(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> userData)
	throws Throwable
	{
		// 上りマッピング処理
		HashMap<String, Object> inMapEKK0061D010 = this.mapper.editInMsgEKK0061D010(param, userData);

		// サービスインターフェース呼び出し
		callSvcInter(handle, param, fixedText, inMapEKK0061D010, new EKK0061D010CBSMsg().getContents());
	}

	/**
	 * 代理店予約取消サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param userData ユーザデータ
	 * @return 予約取消後の更新年月日時分秒
	 * @throws Throwable 例外が発生した場合
	 */
	private String delRsvAgnt(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> userData)
	throws Throwable
	{
		// 上りマッピング処理
		HashMap<String, Object> inMapEKK0061C020 = this.mapper.editInMsgEKK0061C020(param, userData);

		// サービスインターフェース呼び出し
		CAANMsg template = callSvcInter(handle, param, fixedText, inMapEKK0061C020, new EKK0061C020CBSMsg().getContents());
		return template.getString(EKK0061D010CBSMsg.UPD_DTM);
	}

	/**
	 * 代理店変更サービスインターフェースを呼び出します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @param userData ユーザデータ
	 * @throws Throwable
	 */
	private void updAgnt(SessionHandle handle, IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> userData)
	throws Throwable
	{
		// 上りマッピング処理
		HashMap<String, Object> inMapEKK0061C010 = this.mapper.editInMsgEKK0061C010(param, userData);

		// サービスインターフェース呼び出し
		callSvcInter(handle, param, fixedText, inMapEKK0061C010, new EKK0061C010CBSMsg().getContents());
	}


	/**
	 * 引数に値が設定されているか判定します。
	 * <br>
	 * @param str 判定する引数
	 * @return 引数に値が設定されていない場合はtrue
	 */
	public static boolean isNull(String str) 
	{
		if (str == null) 
		{
			return true;
		}

		return 0 == str.toString().trim().length();
	}

	/*
	 * --------------------------------------------------------------------------------------------
	 *  以下共通で使用する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_INVALID_RET_MSG;
			throw new SCCallException(errMsg, String.valueOf(returnCode), templateStatus);
		}
	}

	/**
	 * チェック処理<br>
	 * サービスコンポーネント実行用CAANMsgを返却します。<br>
	 * <br>
	 * 
	 * @param handle セッションハンドル
	 * @param param (I) 業務データ取得用I/F
	 * @param fixedText (I) ユーザ定義文字列
	 * @return サービスコンポーネント実行用CAANMsg
	 * @throws Throwable 例外が発生した場合
	 */
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		HashMap<String, Object> map = new HashMap<String, Object>();
		// SCインプット共通データ
		// **********************************************
		// 【取得元：電文ヘッダ(ヘッダ)】
		// **********************************************
		// 電文ID
		map.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		map.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		map.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		map.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());

		// **********************************************
		// 【取得元：ユーザエリア(コントロールマップ)】
		// **********************************************
		// 依頼先ホスト名
		map.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		map.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		map.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		map.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));

		map.put(JCMConstants.TEMPLATE_LIST_KEY, null);

		return map;
	}

	/**
	 * サービスインターフェイス処理結果(エラー情報)の取得<br>
	 * 業務データ取得・書込用I/Fをそのまま返却します。<br>
	 * <br>
	 * @param param デルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param templates CAANMsgクラス配列
	 * @param returnCode リターンコード
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable 例外が発生した場合
	 */
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param,
			CAANMsg[] templates, int returnCode) throws Throwable
	{
		return param;
	}

	/**
	 * 業務データの取得処理です。
	 * <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;
	}
}
