/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbKK1021SecProc
*	ソースファイル名：JKKejbKK1021SecProc.java
*	作成者			：富士通
*	日付			：2013年03月29日
*＜機能概要＞
*	一時金設定に対する副次処理を行う部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v5.00.00	2013/03/29	FJ）寺本	IT1-2013-0000465
*	v5.00.01	2013/05/27	FJ）竹内	IT2-2013-0000451
*   v5.00.02    2013/09/02  FJ）寺本    OM-2013-0001021
*   v5.00.03    2013/10/31  FJ）沖田    OM-2013-0003570
********************************************************************************/

package eo.ejb.common.db;

import java.util.ArrayList;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0191ETMsg;
import eo.ejb.cbm.entity.KK0251ETMsg;
import eo.ejb.cbm.entity.KK0341ETMsg;
import eo.ejb.cbm.entity.KK0861ETMsg;
import eo.ejb.cbm.entity.KK0891ETMsg;
import eo.ejb.cbm.entity.KK1021ETMsg;
import eo.ejb.cbs.cbsmsg.EKK1021D011CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1021D011CBSMsg1List;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.rule.JKKejbRule0059001;

/**
 * <p>
 * 一時金設定に対する副次処理部品クラスです。
 * </p>
 * @author 富士通
 *
 */
public class JKKejbKK1021SecProc extends JKKejbKK1021DBABase
{
	/** 提供方式コード−提供方式(RULE0059パラメータ)マッピング表 */
	private static final HashMap<String, String> TARGET_TK_HOSHIKI_CD_LIST = new HashMap<String, String>();
	static
	{
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_ENET, JKKModelConst.RULE_TK_HOSHIKI_ENET);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_G_ENET, JKKModelConst.RULE_TK_HOSHIKI_ENET);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_VDSL_1, JKKModelConst.RULE_TK_HOSHIKI_VDSL);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_VDSL_2, JKKModelConst.RULE_TK_HOSHIKI_VDSL);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_VDSL_3, JKKModelConst.RULE_TK_HOSHIKI_VDSL);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_VDSL_4, JKKModelConst.RULE_TK_HOSHIKI_VDSL);
		TARGET_TK_HOSHIKI_CD_LIST.put(JKKModelConst.TK_HOSHIKI_CD_VDSL_5, JKKModelConst.RULE_TK_HOSHIKI_VDSL);
	}

	/**
	 * コンストラクタです。
	 */
	public JKKejbKK1021SecProc()
	{
		super();
	}

	/**
	 * RULE0059(事務手数料判定)を呼び出し、一時金設定の更新処理を行います。
	 * 
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 */
	public void createKK1021(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// 異動区分
		String idoDiv = inCBSMsg.getString(EKK1021D011CBSMsg.IDO_DIV);
		// 申込明細番号
		String mskmDtlNo = inCBSMsg.getString(EKK1021D011CBSMsg.MSKM_DTL_NO);
		// サービス契約番号
		String svcKeiNo = inCBSMsg.getString(EKK1021D011CBSMsg.SVC_KEI_NO);
		// サービス契約内訳番号
		String svcKeiUcwkNo = inCBSMsg.getString(EKK1021D011CBSMsg.SVC_KEI_UCWK_NO);
		// 運用年月日
		String opeDate = JKKModelCommon.getOpeDate(inCBSMsg);
		
		// RULE0059に渡すパラメータを準備する
		// サービス契約番号をKeyにサービス契約のカレントレコードを取得します
		JKKejbKK0081DBABase kk0081dba = new JKKejbKK0081DBABase();
		CAANMsg kk0081CurrentInfo = kk0081dba.getKK0081Current(svcKeiNo, opeDate);
		
		// ルール部品の呼び出し
		JKKejbRule0059001 rule0059 = new JKKejbRule0059001(inCBSMsg);

		// ルール部品パラメータ設定
		rule0059.setSvc_kei_no(svcKeiNo);			// サービス契約番号
		rule0059.setSvc_kei_ucwk_no(svcKeiUcwkNo);	// サービス契約内訳番号
		rule0059.setIdo_div(idoDiv);				// 異動区分
		rule0059.setMskm_dtl_no(mskmDtlNo);			// 申込明細番号
		rule0059.setMskm_prc_grp_cd(kk0081CurrentInfo.getString(KK0081ETMsg.PRC_GRP_CD));	// 申込料金グループコード
		rule0059.setNet_doji_mskm_um(rule0059.getNetDojiMskmUm(mskmDtlNo));					// ネット同時申込有無
		rule0059.setPcrs_cd(kk0081CurrentInfo.getString(KK0081ETMsg.PCRS_CD));				// 料金コースコード
		rule0059.setMans_skb_um(this.getMansionSkbUm(kk0081CurrentInfo));					// マンション識別有無

		// 以下のパラメータは、処理対象のサービス契約内訳がeo光電話の場合に設定する
		if (svcKeiUcwkNo != null && !"".equals(svcKeiUcwkNo))
		{
			// 「サービス契約内訳」単位の事務手数料のみ「一時金設定」を作成する。
			rule0059.setIcjkn_sette_sksi_tani(JKKModelConst.RULE_ICJKN_SETE_TANI_SVKEIUW);	// 一時金設定作成単位
			
			// サービス契約内訳番号をKeyにサービス契約内訳＜eo光電話＞のカレントレコードを取得します
			JKKejbKK0191DBABase kk0191dba = new JKKejbKK0191DBABase();
			CAANMsg kk0191CurrentInfo = kk0191dba.getKK0191Current(svcKeiUcwkNo, opeDate);
			if (kk0191CurrentInfo != null)
			{
				rule0059.setBmp_um(kk0191CurrentInfo.getString(KK0191ETMsg.BMP_UM));		// 番ポ有無
			}
		}

		// 以下のパラメータは、マンション識別有無が"有"の場合に設定する
		if (JKKModelConst.RULE_MANSION_SKBT_CD_U.equals(rule0059.getMans_skb_um()))
		{
			// 提供方式契約を取得
			JKKejbKK0891DBABase kk0891dba = new JKKejbKK0891DBABase();
			CAANMsg kk0891PKInfo = kk0891dba.getKK0891PrimaryInfo(kk0081CurrentInfo.getString(KK0081ETMsg.TK_HOSHIKI_KEI_NO));

			// ルール部品パラメータ設定
			rule0059.setTk_hoshiki(this.getTkHoshiki(kk0891PKInfo)); 		// 提供方式
			rule0059.setTk_prc_sbt_cd(this.getTkPrcSbtCd(kk0891PKInfo)); 	// 提供料金種別コード
			rule0059.setModem_rental_kbn(this.getModemRentalKbn(inCBSMsg));	// 機器提供種別コード
		}

		// ルールの実行
		CAANMsg[] rule0059ResultList = rule0059.invoke();
		
		// アウト項目を詰めるリスト
		ArrayList<CAANMsg> outList = new ArrayList<CAANMsg>();
		
		// 更新結果をアウトに詰める
		for (CAANMsg rule0059Result : rule0059ResultList)
		{
			CAANMsg outMsg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKK1021D011CBSMsg1List");
			outMsg.set(EKK1021D011CBSMsg1List.ICJKN_SETTE_NO, rule0059Result.getString(KK1021ETMsg.ICJKN_SETTE_NO));
			outMsg.set(EKK1021D011CBSMsg1List.ICJKN_HASSEI_YMD, rule0059Result.getString(KK1021ETMsg.ICJKN_HASSEI_YMD));
			outMsg.set(EKK1021D011CBSMsg1List.ADD_DTM, rule0059Result.getString(KK1021ETMsg.ADD_DTM));
			outMsg.set(EKK1021D011CBSMsg1List.ADD_OPEACNT, rule0059Result.getString(KK1021ETMsg.ADD_OPEACNT));
			outMsg.set(EKK1021D011CBSMsg1List.UPD_DTM, rule0059Result.getString(KK1021ETMsg.UPD_DTM));
			outMsg.set(EKK1021D011CBSMsg1List.UPD_OPEACNT, rule0059Result.getString(KK1021ETMsg.UPD_OPEACNT));
			outMsg.set(EKK1021D011CBSMsg1List.MK_FLG, rule0059Result.getString(KK1021ETMsg.MK_FLG));
			
			outList.add(outMsg);
		}
		
		// アウトメッセージを設定する
		inCBSMsg.set(EKK1021D011CBSMsg.EKK1021D011CBSMSG1LIST, outList.toArray(new CAANMsg[0]));
	}

	/**
	 * <p>
	 * マンション識別有無を取得します
	 * </p>
	 * @param kk0081CurrentInfo サービス契約のカレント
	 * @return 無 / 有
	 */
	private String getMansionSkbUm(CAANMsg kk0081CurrentInfo)
	{
		// サービス契約.提供方式契約番号
		return getMansionSkbUm(kk0081CurrentInfo.getString(KK0081ETMsg.TK_HOSHIKI_KEI_NO), JKKModelCommon.getOpeDate(kk0081CurrentInfo));
	}


	/**
	 * <p>
	 * マンション識別有無を取得します
	 * </p>
	 * @param kk0081CurrentInfo サービス契約のカレント
	 * @return 無 / 有
	 */
	public String getMansionSkbUm(String tkHoshikiKeiNo, String opeDate) {

		
		// 提供方式契約番号が未設定の場合は、マンション子契約でない
		if (tkHoshikiKeiNo == null || "".equals(tkHoshikiKeiNo))
		{
			return JKKModelConst.RULE_MANSION_SKBT_CD_M;
		}
		
		// 提供方式契約番号に紐づくマンション物件明細を取得します
		JKKejbKK0861DBABase kk0861dba = new JKKejbKK0861DBABase();
		CAANMsg kk0861Msg = kk0861dba.getKK0861byTkHoshikiKei(tkHoshikiKeiNo, null, opeDate);
		
		// マンション物件コードが"マンション"の場合
		if (JKKModelConst.MANSION_BUKKEN_CD_MANS.equals(kk0861Msg.getString(KK0861ETMsg.MANSION_BUKKEN_CD)))
		{
			return JKKModelConst.RULE_MANSION_SKBT_CD_U;
		}
		return JKKModelConst.RULE_MANSION_SKBT_CD_M;
	}

	/**
	 * <p>
	 * モデムレンタル区分を取得します
	 * </p>
	 * @param inCSBMsg 処理対象のメッセージキャリア
	 * @return 機器提供種別コード
	 */
	private String getModemRentalKbn(CAANMsg inCSBMsg)
	{
		// 該当の「サービス契約」が使用する「サービス契約回線内訳」を取得します
		JKKejbKK0251DBABase kk0251dba = new JKKejbKK0251DBABase();
		CAANMsg[] kk0251InfoList = kk0251dba.getKK0251bySvcKei(inCSBMsg.getString(EKK1021D011CBSMsg.SVC_KEI_NO),
				null, JKKModelCommon.getOpeDate(inCSBMsg), "1");

		// 検索結果格納用
		ArrayList<CAANMsg> resultList = new ArrayList<CAANMsg>();
		
		for (CAANMsg kk0251Info : kk0251InfoList)
		{
			// 個別検索条件マップ
			HashMap<String, String[]> searchJknMap = new HashMap<String, String[]>();
			// 追加検索条件：機器提供サービス契約.機器提供サービスコード = "モデム"
			String [] kktkSvcCdList = {JKKModelConst.KKTK_SVC_CD_MODEM};
			searchJknMap.put(KK0341ETMsg.KKTK_SVC_CD, kktkSvcCdList);
			
			// 該当の「サービス契約回線内訳」で使用する「機器提供サービス契約」(モデム)を取得します
			JKKejbKK0341DBABase kk0341dba = new JKKejbKK0341DBABase();
			CAANMsg[] kk0341InfoList = kk0341dba.getKK0341bySvcKeiKaisenUcwk(kk0251Info.getString(KK0251ETMsg.SVC_KEI_KAISEN_UCWK_NO),
					searchJknMap, JKKModelCommon.getOpeDate(inCSBMsg));
			
			for (CAANMsg kk0341Info : kk0341InfoList)
			{
				// ステータスが「解約」or「キャンセル」の場合
				String status = kk0341Info.getString(KK0341ETMsg.KKTK_SVC_KEI_STAT);
				if (JKKModelConst.KKTK_SVC_KEI_STAT_DSL_ZM.equals(status) || JKKModelConst.KKTK_SVC_KEI_STAT_CNCL_ZM.equals(status))
				{
					continue;
				}
				
				// リストに詰める
				resultList.add(kk0341Info);
			}
		}

		// サービスに紐付く機器が2件以上あった場合、機器提供サービス契約「更新年月日時分秒」が最新の機器を対象とする
		CAANMsg kk0341MaxUpdateData = null;
		for (CAANMsg kk0341date : resultList)
		{
			if (kk0341MaxUpdateData == null
					|| kk0341date.getString(KK0341ETMsg.UPD_DTM).compareTo(kk0341MaxUpdateData.getString(KK0341ETMsg.UPD_DTM)) > 0)
			{
				kk0341MaxUpdateData = kk0341date;
			}
		}

		// 取得できなかった場合
		if (kk0341MaxUpdateData == null)
		{
			return null;
		}
		
		// 機器提供種別コードを返却する
		return kk0341MaxUpdateData.getString(KK0341ETMsg.KKTK_SBT_CD);
	}

	/**
	 * <p>
	 * 提供料金種別コードを取得します
	 * </p>
	 * @param kk0891PKInfo 提供方式契約のPKレコード
	 * @return VDSL-S方式 / VDSL-S方式以外
	 */
	public String getTkPrcSbtCd(CAANMsg kk0891PKInfo)
	{
		// 提供料金種別コードを取得する
		String tkPrcSbtCd = kk0891PKInfo.getString(KK0891ETMsg.TK_PRC_SBT_CD);

		// 提供料金種別コードが"旧VDSL-S方式"、"VDSL-S方式"の場合
		if (JKKModelConst.TK_PRC_SBT_CD_OLD_VDSL_S_HSK.equals(tkPrcSbtCd) || JKKModelConst.TK_PRC_SBT_CD_VDSL_S_HSK.equals(tkPrcSbtCd))
		{
			return JKKModelConst.RULE_TK_PRC_SBT_CD_VDSL_S;
		}
		
		// 提供料金種別コードが上記以外(NULL含む)の場合
		return JKKModelConst.RULE_TK_PRC_SBT_CD_NOT_VDSL_S;
	}

	/**
	 * <p>
	 * 提供方式を取得します
	 * </p>
	 * @param kk0891PKInfo 提供方式契約のPKレコード
	 * @return VDSL / イーサネット
	 */
	public String getTkHoshiki(CAANMsg kk0891PKInfo)
	{
		// 提供方式コードが未設定の場合はnullを返却します
		if (kk0891PKInfo.isNull(KK0891ETMsg.TK_HOSHIKI_CD))
		{
			return null;
		}

		// 提供方式コードを取得
		String tkHoshikiCd = kk0891PKInfo.getString(KK0891ETMsg.TK_HOSHIKI_CD);

		// 提供方式のマップに存在する場合
		if (TARGET_TK_HOSHIKI_CD_LIST.containsKey(tkHoshikiCd))
		{
			// イーサネットまたはVDSLの値を設定する
			return TARGET_TK_HOSHIKI_CD_LIST.get(tkHoshikiCd);
		}

		return null;
	}

	/**
	 * <p>
	 * 住居形態を取得します
	 * </p>
	 * @param inCSBMsg 処理対象のメッセージキャリア
	 * @param tkHoshikiKeiNo 提供方式契約番号
	 * @return ホーム / メゾン / マンション
	 */
	public String getJkForm(CAANMsg inCSBMsg, String tkHoshikiKeiNo)
	{
		// 提供方式契約番号が未設定(マンション子契約でない)の場合
		if (tkHoshikiKeiNo == null)
		{
			return JKKModelConst.JK_FORM_HOME;
		}
		
		// 提供方式契約番号に紐づくマンション物件明細を取得します
		JKKejbKK0861DBABase kk0861dba = new JKKejbKK0861DBABase();
		CAANMsg kk0861Msg = kk0861dba.getKK0861byTkHoshikiKei(tkHoshikiKeiNo, null, JKKModelCommon.getOpeDate(inCSBMsg));
		
		// マンション物件コードが"マンション"の場合
		if (JKKModelConst.MANSION_BUKKEN_CD_MANS.equals(kk0861Msg.getString(KK0861ETMsg.MANSION_BUKKEN_CD)))
		{
			return JKKModelConst.JK_FORM_MANS;
		}
		// マンション物件コードが"メゾン"の場合
		else if (JKKModelConst.MANSION_BUKKEN_CD_MAISON.equals(kk0861Msg.getString(KK0861ETMsg.MANSION_BUKKEN_CD)))
		{
			return JKKModelConst.JK_FORM_MAISON;
		}
		else
		{
			throw new CAANRuntimeException("未定義のマンション物件コードです。");
		}
	}

}
