/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbEKK0111C030Edit
*	ソースファイル名：JKKejbEKK0111C030Edit.java
*	作成者			：富士通
*	日付			：2011年11月14日
*＜機能概要＞
*	サービス契約<eo光電話>開始相関ルールチェック部品部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00    2011/11/14  富士通      新規作成
*
********************************************************************************/

package eo.ejb.common.edit;

import java.util.ArrayList;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0161ETMsg;
import eo.ejb.cbm.entity.KK0161LE;
import eo.ejb.cbm.entity.KK0191ETMsg;
import eo.ejb.cbm.entity.KK0781ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0111C030CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0021DBABase;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0161DBABase;
import eo.ejb.common.db.JKKejbKK0191DBABase;
import eo.ejb.common.db.JKKejbKK0781DBABase;
import eo.ejb.common.rule.JKKejbRule0065001;
import eo.ejb.common.rule.JKKejbRule0073001;

/**
 * <p>
 * サービス契約<eo光電話>開始相関ルールチェック部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbEKK0111C030Edit
{

	/** サービスコード（インターネットサービス）*/
	private static final String SVC_CD_NET = "01";

	/** インターネットサービス同時申込有無（同時申込有り）*/
	private static final String NET_DOUJI_ARI = "1";

	/** インターネットサービス同時申込有無（同時申込無し）*/
	private static final String NET_DOUJI_NASHI = "0";

	/** 無効フラグ（有効）*/
	private static final String MK_FLG_VALID = "0";

	/**
	 * <p>
	 * 新しいJKKejbEKK0111C030Editを作成します。
	 * </p>
	 */
	public JKKejbEKK0111C030Edit()
	{
	}

	/**
	 * <p>
	 * 開始日設定(サービス)の相関ルールにより開始日を算出する。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 開始日
	 */
	public Object getStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0111C030Edit#getStaYmd");

		// サービス契約のカレントレコードを取得
		CAANMsg ret0081 = getCurrentKK0081(inCBSMsg, inCBSMsg.getString(EKK0111C030CBSMsg.SVC_KEI_NO));

		// 料金グループのカレントレコードを取得
		CAANMsg ret0781 = getCurrentKK0781(inCBSMsg, ret0081.getString(KK0081ETMsg.PRC_GRP_CD));

		// サービス契約内訳<eo光電話>の全件カレントレコードを取得
		CAANMsg[] ret0191List = getAllCurrentKK0191(inCBSMsg, inCBSMsg.getString(EKK0111C030CBSMsg.SVC_KEI_NO));

		// 開始年月日保持用リスト
		ArrayList<String> arrayStaYmd = new ArrayList<String>();
		
		for (int i = 0; i < ret0191List.length; i++)
		{
			// 開始日設定(サービス)の相関ルール部品呼び出し
			JKKejbRule0073001 rule0073 = new JKKejbRule0073001(inCBSMsg);

			// パラメータ設定
			rule0073.setSvc_cd(ret0081.getString(KK0081ETMsg.SVC_CD));
			rule0073.setKaisen_tk_comp_cd(ret0781.getString(KK0781ETMsg.KAISEN_TK_COMP_CD));
			rule0073.setPrc_grp_cd(ret0081.getString(KK0081ETMsg.PRC_GRP_CD));
			rule0073.setBmp_um(ret0191List[i].getString(KK0191ETMsg.BMP_UM));
			rule0073.setIdo_div(inCBSMsg.getString(EKK0111C030CBSMsg.IDO_DIV));
			rule0073.setKkshka_um(inCBSMsg.getString(EKK0111C030CBSMsg.KKSHKA_UM));
			rule0073.setSvc_kei_no(inCBSMsg.getString(EKK0111C030CBSMsg.SVC_KEI_NO));
			rule0073.setSvc_kei_ucwk_no(ret0191List[i].getString(KK0191ETMsg.SVC_KEI_UCWK_NO));
			rule0073.setMskm_dtl_no(ret0081.getString(KK0081ETMsg.MSKM_DTL_NO));
			rule0073.setSvc_use_sta_kibo_ymd(ret0081.getString(KK0081ETMsg.SVC_USE_STA_KIBO_YMD));
			rule0073.setShosa_ymd(ret0081.getString(KK0081ETMsg.SHOSA_YMD));

			// ルールの呼び出し
			String staDate = rule0073.getStaYmd();

			// 取得した開始日がnullでない場合は、リストに保持する
			if (null != staDate) 
			{
				arrayStaYmd.add(rule0073.getStaYmd());
			}
		}

		String staYmd = null; 

		// 取得した開始日の個数分処理を行う
		for (int i = 0; i < arrayStaYmd.size(); i++)
		{
			// 1件目の場合は値をそのまま開始日に設定する
			if (i == 0)
			{
				staYmd = arrayStaYmd.get(i);
				continue;
			}

			// 現在設定される開始日より、リストの開始日が大きい場合、
			// リストの開始日を開始日とする
			if (staYmd.compareTo(arrayStaYmd.get(i)) < 0)
			{
				staYmd = arrayStaYmd.get(i);
			}
		}
		
		// 開始年月日が取得できなかった場合、エラー処理を行う。
		if(null == staYmd || "".equals(staYmd))
		{
			setError(inCBSMsg);
			return null;
		}

		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "end:JKKejbEKK0111C030Edit#getStaYmd");

		return staYmd;
	}

	/**
	 * <p>
	 * 課金開始日設定(サービス)の相関ルールにより課金開始日を算出する。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 課金開始日
	 */
	public Object getChrgStaYmd(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0111C030Edit#getChrgStaYmd");

		// サービス契約のカレントレコードを取得
		CAANMsg ret0081 = getCurrentKK0081(inCBSMsg, inCBSMsg.getString(EKK0111C030CBSMsg.SVC_KEI_NO));
		
		// 料金グループのカレントレコードを取得
		CAANMsg ret0781 = getCurrentKK0781(inCBSMsg, ret0081.getString(KK0081ETMsg.PRC_GRP_CD));

		// 開始日設定(サービス)の相関ルール部品呼び出し
		JKKejbRule0065001 rule0065 = new JKKejbRule0065001(inCBSMsg);

		// パラメータ設定
		rule0065.setIdo_div(ret0081.getString(KK0081ETMsg.IDO_DIV));
		rule0065.setSvc_cd(ret0081.getString(KK0081ETMsg.SVC_CD));
		rule0065.setPrc_grp_cd(ret0081.getString(KK0081ETMsg.PRC_GRP_CD));
		rule0065.setKaisen_tk_comp_cd(ret0781.getString(KK0781ETMsg.KAISEN_TK_COMP_CD));
		rule0065.setMskm_dtl_no(ret0081.getString(KK0081ETMsg.MSKM_DTL_NO));

		Object staYmd = getStaYmd(inCBSMsg, inContext);

		if (null == staYmd)
		{
			setError(inCBSMsg);
			return null;
		}

		rule0065.setSvc_sta_ymd(staYmd.toString());

		String doujiMskm = getInsvcDojiMskmUm(inCBSMsg, ret0081.getString(KK0081ETMsg.MSKM_DTL_NO));
		
		// インターネットサービス同時申込有無が取得できなかった場合、エラー処理を行う。
		if(null == doujiMskm || "".equals(doujiMskm))
		{
			setError(inCBSMsg);
			return null;
		}

		rule0065.setInsvc_doji_mskm_um(doujiMskm);

		// ルールの呼び出し
		String chrgStaYmd = rule0065.getChrgStaYmd();

		// 開始年月日が取得できなかった場合、エラー処理を行う。
		if(null == chrgStaYmd || "".equals(chrgStaYmd))
		{
			setError(inCBSMsg);
			return null;
		}

		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "end:JKKejbEKK0111C030Edit#getChrgStaYmd");

		return chrgStaYmd;
	}

	/**
	 * <p>
	 * インターネットサービス同時申込有無の設定値を取得します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param mskmDtlNo 申込明細番号
	 * @return インターネットサービス同時申込有無
	 */
	private String getInsvcDojiMskmUm(CAANMsg inCBSMsg, String mskmDtlNo)
	{
		// 申込明細のカレントレコードを取得
		CAANMsg ret0021 = getCurrentKK0021(inCBSMsg, mskmDtlNo);

		// 申込番号に紐付くサービス契約の全件を取得
		CAANMsg[] ret0081All = new JKKejbEditUtil().getCurKK0081WithMskm(inCBSMsg, ret0021.getString(KK0021ETMsg.MSKM_NO));

		// 取得したサービス契約の件数分処理を行う
		for (int j = 0; j < ret0081All.length; j++)
		{
			// サービスコードが「インターネットサービス」のレコードが存在した場合、
			// 同時申込有りを返却する
			if (SVC_CD_NET.equals(ret0081All[j].getString(KK0081ETMsg.SVC_CD)))
			{
				return NET_DOUJI_ARI;
			}
		}

		// サービスコードが「インターネットサービス」のレコードが存在しなかった場合、
		// 同時申込無しを返却する
		return NET_DOUJI_NASHI;
	}

	/**
	 * <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 処理対象のメッセージキャリア
	 * @return 検索結果のレコード
	 */
	private CAANMsg getPrimaryKK0191(CAANMsg inCBSMsg)
	{
		// 一意検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0191ETMsg.class.getName());
		inETMsg.set(KK0191ETMsg.SVC_KEI_UCWK_NO, inCBSMsg.getString(KK0191ETMsg.SVC_KEI_UCWK_NO));
		inETMsg.set(KK0191ETMsg.GENE_ADD_DTM, inCBSMsg.getString(KK0191ETMsg.GENE_ADD_DTM));

		// サービス契約内訳<eo光電話>の一意検索を行う
		return new JKKejbKK0191DBABase().findByPrimaryKey(inETMsg);
	}
	
	/**
	 * <p>
	 * 料金グループのカレント検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param prcGrpCd 料金グループコード
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0781(CAANMsg inCBSMsg, String prcGrpCd)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0781ETMsg.class.getName());
		inETMsg.set(KK0781ETMsg.PRC_GRP_CD, prcGrpCd);
		inETMsg.set(KK0781ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		// 料金グループのカレント検索を行う
		return new JKKejbKK0781DBABase().findByCurrent(inETMsg);
	}
	
	/**
	 * <p>
	 * 申込明細のカレント検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param mskmDtlNo 申込明細番号
	 * @return 検索結果のレコード
	 */
	private CAANMsg getCurrentKK0021(CAANMsg inCBSMsg, String mskmDtlNo)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0021ETMsg.class.getName());
		inETMsg.set(KK0021ETMsg.MSKM_DTL_NO, mskmDtlNo);

		// 申込明細のカレント検索を行う
		return new JKKejbKK0021DBABase().findByCurrent(inETMsg);
	}
	
	/**
	 * <p>
	 * サービス契約番号に紐付くサービス契約内訳<eo光電話>の全件カレント検索を行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo サービス契約番号
	 * @return 検索結果のレコード配列
	 */
	private CAANMsg[] getAllCurrentKK0191(CAANMsg inCBSMsg, String svcKeiNo)
	{
		// 全件検索用のメッセージを作成
		CAANMsg inETMsgCnd = new CAANMsg(KK0161ETMsg.class.getName());
		inETMsgCnd.set(KK0161ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsgCnd.set(KK0161ETMsg.MK_FLG, MK_FLG_VALID);

		// サービス契約内訳の全件検索を行う
		CAANMsg[] ret0161Cnd = null;

		try
		{
			ret0161Cnd = new KK0161LE().findByCondition(inETMsgCnd);
		}
		catch(CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// カレント取得結果の保持用リスト
		ArrayList<CAANMsg> array = new ArrayList<CAANMsg>();

		// 処理済キー保持用HashMap
		HashMap<String, String> hash = new HashMap<String, String>();
		
		// サービス契約の取得件数分処理を行う
		for (int i = 0; i < ret0161Cnd.length; i++)
		{
			// サービス契約内訳番号の取得
			String svcKeiUcwkNo = ret0161Cnd[i].getString(KK0161ETMsg.SVC_KEI_UCWK_NO);
			
			// 処理済のサービス契約内訳番号は処理しない
			if (hash.containsKey(svcKeiUcwkNo))
			{
				continue;
			}

			// 処理済のサービス契約内訳番号をHashMapに保持する
			hash.put(svcKeiUcwkNo, svcKeiUcwkNo);

			// 対象のサービス内訳契約番号でカレント検索を行う
			CAANMsg ret0161 = getCurrentKK0161(inCBSMsg, svcKeiUcwkNo);

			// 対象のサービス内訳契約番号でサービス契約内訳<eo光電話>の一意検索を行う
			CAANMsg ret0191 = getPrimaryKK0191(ret0161);

			array.add(ret0191);

		}
		
		// カレント検索の結果をリストからCAANMsgの配列へ置換する
		CAANMsg[] retMsg = new CAANMsg[array.size()];

		for (int i = 0; i < array.size(); i++)
		{
			retMsg[i] = array.get(i);
		}

		return retMsg;
	}
	
	/**
	 * <p>
	 * 関連制約エラーを設定します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 */
	private void setError(CAANMsg inCBSMsg)
	{
		// 相関エラーのステータスを設定
		inCBSMsg.set(EKK0111C030CBSMsg.SVC_KEI_NO_ERR, "ED");
		inCBSMsg.set(EKK0111C030CBSMsg.STATUS, StatusCodes.RELATION_ERR);
	}

}
