/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUSameSeikyusakiCheckCC
*   ソースファイル名：JFUSameSeikyusakiCheckCC.java
*   作成者          ：富士通
*   日付            ：2012年3月28日
*＜機能概要＞
*   同一請求先チェックコンポーネント部品
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2012/03/28   FJ）今村    新規作成
*   v1.01.00    2013/02/13   FJ）大塚    No224対応
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

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.exception.SCCallException;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;

import eo.common.constant.JFUStrConst;
import eo.common.constant.JPCModelConstant;
import eo.ejb.cbs.cbsmsg.EKK0081B524CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081B524CBSMsg1List;

/**
 * 同一請求先チェックコンポーネント部品
 * <br>
 * @author 富士通
 */
@SuppressWarnings("unchecked")
public class JFUSameSeikyusakiCheckCC extends JFUBaseCC
{
	/** テンプレートID(サービス契約一覧照会（同一請求先回線情報取得）) */
	private static final String TEMPLATE_ID_EKK0081B524 = "EKK0081B524";
	/** テンプレートID(サービス契約一覧照会（同一請求先回線情報取得）明細) */
	private static final String TEMPLATE_ID_DETAIL_EKK0081B524 = "EKK0081B524CBSMsg1List";
	/** IN項目リスト(サービス契約一覧照会（同一請求先回線情報取得）) */
	private static final List<String> IN_COLUMN_EKK0081B524 = Arrays.asList(EKK0081B524CBSMsg.KEY_SYSID, EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO);

	/** 関連チェックエラー項目(サービス契約一覧照会（同一請求先回線情報取得）) */
	private static final String ERROR_COLUMN_SVC_KEI_NO = "svc_kei_no_err";
	//	/** 同一請求先の最大件数 */
	//	private static final int MAX_SAME_SEIKYUSAKI_CNT = 5;
	/** 同一請求先の最大件数 */
	private static final String MAX_SAME_SEIKYUSAKI_CNT = "MAX_SAME_SEIKYUSAKI_CNT";

	/**
	 * 同一請求先チェック処理<br>
	 * 
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return リクエストパラメータ管理クラス
	 * @throws Exception 例外
	 */
	public IRequestParameterReadWrite executeCheck(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Exception
	{
		HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(fixedText);
		// No224 Otsuka 2013/02/13 start
		// データが存在しない場合は処理を行わない。
		if ((inMap == null) || (inMap.isEmpty()))
		{
			return param;
		}
		// No224 Otsuka 2013/02/13 end

		// 機能コード取得(1:チェック＆登録, 2:チェックのみ)
		String funcCode = getFuncCode(param, fixedText);

		// マップ(inMap)からマップ(ccMap)へ値をコピー

		HashMap<String, Object> ccMap = new HashMap<String, Object>();
		copyMap(inMap, ccMap);

		// SIF:サービス契約一覧照会（同一請求先回線情報取得）
		// 上りマッピング項目設定
		setInMapEKK0081B524(param, fixedText, ccMap);
		// サービスIF実行 
		executeSC(handle, param, fixedText, TEMPLATE_ID_EKK0081B524, TEMPLATE_ID_DETAIL_EKK0081B524, IN_COLUMN_EKK0081B524, "");

		// 2012.5.21 障害対応 （検索結果がnullの場合にチェックを実施しない）
		HashMap<String, Object> resultMap = (HashMap<String, Object>)param.getData(fixedText);
		ArrayList<Object> childList = (ArrayList<Object>)resultMap.get(TEMPLATE_ID_DETAIL_EKK0081B524);
		if (childList != null)
		{
			// 同一請求先チェック処理
			checkEKK0081B524(param, fixedText, funcCode, ccMap);
		}

		return param;
	}

	/**
	 * チェック処理
	 * 
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return リクエストパラメータ
	 * @throws Exception
	 */
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Exception
	{
		return null;
	}

	/**
	 * 上りマッピング項目設定(サービス契約一覧照会（同一請求先回線情報取得）)
	 * 
	 * <br>
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @param ccMap CCマップ
	 * @throws RequestParameterException
	 */
	private void setInMapEKK0081B524(IRequestParameterReadWrite param, String fixedText, HashMap<String, Object> ccMap)
			throws RequestParameterException
	{
		// 検索エラーなし設定
		ignoreSearchError(param, fixedText);

		HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(fixedText);
		// 必須入力項目
		inMap.put(EKK0081B524CBSMsg.KEY_SYSID, ccMap.get(EKK0081B524CBSMsg.KEY_SYSID));

		// No224 Otsuka 2013/02/13 start
		if (ccMap.get(EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO) == null || "".equals(ccMap.get(EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO)))
		{
			inMap.put(EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO, null);
		}
		else
		{
			inMap.put(EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO, ccMap.get(EKK0081B524CBSMsg.KEY_SEIKY_KEI_NO));
		}
		// No224 Otsuka 2013/02/13 end
	}

	/**
	 * 同一請求先チェック処理(サービス契約一覧照会（同一請求先回線情報取得）)
	 * <br>
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @throws RequestParameterException
	 * @throws SCCallException
	 */
	private void checkEKK0081B524(IRequestParameterReadWrite param, String fixedText, String funcCode, HashMap<String, Object> ccMap)
			throws RequestParameterException, SCCallException
	{
		int sameCnt = 0;
		int netCnt = 0;
		String prevSeikyKeiNo = "";
		HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(fixedText);
		ArrayList<Object> childList = (ArrayList<Object>)inMap.get(TEMPLATE_ID_DETAIL_EKK0081B524);

		// No224 Otsuka 2013/02/13 start
		// ネットフラグ
		Boolean netFlg = false;
		// ハイブリッドフラグ
		Boolean hbFlg = false;
		// 使用できる請求先の数
		int useCnt = 0;

		// ハイブリッドのネット1回線に対しての最大契約数
		int maxKeiCnt = Integer.parseInt((String)ccMap.get("max_same_seikyusaki_cnt"));

		// ループ：サービス契約一覧照会（同一請求先回線情報取得）件数分
		for (int i = 0; i < childList.size(); i++)
		{
			HashMap<String, String> childMap = (HashMap<String, String>)childList.get(i);
			String prcGrpCd = childMap.get(EKK0081B524CBSMsg1List.PRC_GRP_CD);
			String seikyKeiNo = childMap.get(EKK0081B524CBSMsg1List.SEIKY_KEI_NO);

			String pcrsCd = childMap.get(EKK0081B524CBSMsg1List.PCRS_CD);

			// フラグ初期化
			netFlg = false;
			hbFlg = false;

			// 料金グループコードがネット(02・03・04)の場合
			if (JFUStrConst.CD00133_02.equals(prcGrpCd) || JFUStrConst.CD00133_03.equals(prcGrpCd) || JFUStrConst.CD00133_04.equals(prcGrpCd))
			{
				netFlg = true;
			}

			// 料金コースコードがハイブリッドタイプの場合
			if (JFUStrConst.CD00134_A59.equals(pcrsCd) || JFUStrConst.CD00134_A60.equals(pcrsCd))
			{
				hbFlg = true;
			}

			// どちらでもない場合
			if (!netFlg && !hbFlg)
			{
				// 次の処理へ
				continue;
			}

			if (i == 0)
			{
				// 料金グループコードがネット(02・03・04)の場合
				if (netFlg)
				{
					netCnt++; // ネット件数カウント
				}

				// 料金コースコードがハイブリッドタイプの場合
				if (hbFlg)
				{
					sameCnt++; // ハイブリッド件数カウント
				}
			}
			else
			{
				// １つ前の請求契約番号と今回の請求契約番号が同じ場合
				if (prevSeikyKeiNo.equals(seikyKeiNo))
				{
					// 料金グループコードがネット(02・03・04)の場合
					if (netFlg)
					{
						netCnt++; // ネット件数カウント
					}

					// 料金コースコードがハイブリッドタイプの場合
					if (hbFlg)
					{
						sameCnt++; // ハイブリッド件数カウント
					}
				}
				// 請求契約番号が変わったタイミング。
				else
				{
					// 回線数がネットの契約数×N回線より多い場合
					if (maxKeiCnt * netCnt <= sameCnt)
					{
						// カウント初期化
						netCnt = 0;
						sameCnt = 0;

						// 料金グループコードがネット(02・03・04)の場合
						if (netFlg)
						{
							netCnt++; // ネット件数カウント
						}

						// 料金コースコードがハイブリッドタイプの場合
						if (hbFlg)
						{
							sameCnt++; // ハイブリッド件数カウント
						}
					}
					else
					{
						// 使用できる請求先の数カウント
						useCnt++;

						// カウント初期化
						netCnt = 0;
						sameCnt = 0;

						// 料金グループコードがネット(02・03・04)の場合
						if (netFlg)
						{
							netCnt++; // ネット件数カウント
						}

						// 料金コースコードがハイブリッドタイプの場合
						if (hbFlg)
						{
							sameCnt++; // ハイブリッド件数カウント
						}
					}
				}
			}
			// 前回の請求契約番号に今回の値を上書き
			prevSeikyKeiNo = seikyKeiNo;
		}

		// ネットが1回線以上かつ、ハイブリッドの合計回線数がネットの契約数×N回線より少ない場合
		if (netCnt >= 1 && (maxKeiCnt * netCnt > sameCnt))
		{
			// 使用できる請求先の数カウント
			useCnt++;
		}

		// 使用できる請求先の数が0の場合
		if (useCnt == 0)
		{
			// 同一請求先が5件以上の場合、エラーとする
			setRelationErrorInfo(param, TEMPLATE_ID_EKK0081B524, ERROR_COLUMN_SVC_KEI_NO, fixedText);
			String msg = String.valueOf(param.getControlMapData(SCControlMapKeys.RETURN_MESSAGE));
			throw new SCCallException(msg, String.valueOf(RETURN_CODE_NORMAL), JPCModelConstant.RELATION_ERR);
		}
		// No224 Otsuka 2013/02/13 end
	}

	/**
	 * マップからマップへ値をコピーします
	 * <br>
	 * @param srcMap 取得元マップ
	 * @param destMap 取得先マップ
	 */
	private void copyMap(HashMap<String, Object> srcMap, HashMap<String, Object> destMap)
	{
		if (srcMap != null && destMap != null)
		{
			for (String srcKey : srcMap.keySet())
			{
				destMap.put(srcKey, srcMap.get(srcKey));
			}
		}
	}
}