/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbRule0089002
*	ソースファイル名：JKKejbRule0089002.java
*	作成者			：富士通
*	日付			：2013年02月15日
*＜機能概要＞
*	サービス課金開始年月日判定相関ルール部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v5.00.00	2013/02/15	FJ)			新規作成
*   v5.00.01    2013/03/01  FJ)寺本     IT2-2013-0000238
*   v5.00.02    2013/09/01  FJ)寺本     OM-2013-0001240
**********************************************************************/

package eo.ejb.common.rule;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;

import eo.ejb.cbm.entity.KK0451ETMsg;
import eo.ejb.cbm.entity.KK2361ETMsg;
import eo.ejb.cbm.entity.KK2371ETMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0451DBABase;
import eo.ejb.common.db.JKKejbKK2361DBABase;
import eo.ejb.common.db.JKKejbKK2371DBABase;

/**
 * <p>
 * サービス課金開始年月日判定相関ルール部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbRule0089002 extends JKKejbRuleBase
{
	/** ルールID */
	private static final String RULE_ID = "RULE0089002";

	/** 判定結果 */
	private static final String JUDGE_RSLT = "JUDGE_RSLT";

	/** キャンペーン開始コード */
	private static final String CAMPAIGN_STA_CD = "CAMPAIGN_STA_CD";

	/** 割引登録年月日 */
	private static final String WRIB_ADD_YMD = "WRIB_ADD_YMD";
	
	/** 割引登録年月日当月1日 */
	private static final String WRIB_ADD_YMD_TG_ONE_DAY = "WRIB_ADD_YMD_TG_ONE_DAY";

	/** 割引適用基準年月日 */
	private static final String WRIB_TEKIO_STDARDYMD = "WRIB_TEKIO_STDARDYMD";

	/** 割引課金開始月指定コード */
	private static final String WRIB_CHRG_STA_MON_STI_CD = "WRIB_CHRG_STA_MON_STI_CD";

	/** 判定結果：上記以外 */
	private static final String JUDGE_RSLT_NOT_SET = "0";

	/** 判定結果：割引適用基準年月日 */
	private static final String JUDGE_RSLT_WRIB_TEKIO_STDARDYMD = "1";

	/** 判定結果：割引登録年月日の翌月１日 */
	private static final String JUDGE_RSLT_WRIB_ADD_YMD_YKGTU_FIRST = "2";

	/** 判定結果：割引登録年月日の前月１日 */
	private static final String JUDGE_RSLT_WRIB_ADD_YMD_ZNGTU_FIRST = "3";

	/** 判定結果：割引登録年月日の当月１日 */
	private static final String JUDGE_RSLT_WRIB_ADD_YMD_TOGTU_FIRST = "4";

	/** 判定結果：割引適用基準年月日の当月１日 */
	private static final String JUDGE_RSLT_WRIB_TEKIO_STDARDYMD_TOGTU_FIRST = "5";

	/** 判定結果：割引適用基準年月日の翌月１日 */
	private static final String JUDGE_RSLT_WRIB_TEKIO_STDARDYMD_NEMO_FIRST = "6";

	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** キャンペーン開始コード */
	private String campaign_sta_cd = null;

	/** 割引登録年月日 */
	private String wrib_add_ymd = null;
	
	/** 割引登録年月日当月1日 */
	private String wrib_add_ymd_tg_one_day = null;

	/** 割引適用基準年月日 */
	private String wrib_tekio_stdardymd = null;
	
	/** 割引課金開始月指定コード */
	private String wrib_chrg_sta_mon_sti_cd = null;	

	/** 割引サービス契約番号 */
	private String wrib_svc_kei_no = null;

	/** 割引サービス契約カレント情報 */
	private CAANMsg kk0451Info = null;
	
	/**
	 * <p>
	 * JKKejbRule0088001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0089002(CAANMsg inMsg)
	{
		super();
		this.inCBSMsg = inMsg;
	}

	/**
	 * <p>
	 * 処理対象のCBSMsgを取得します。
	 * </p>
	 * @return 処理対象のCBSMsg
	 */
	protected CAANMsg getCBSMsg()
	{
		return this.inCBSMsg;
	}

	/**
	 * <p>
	 * ルールIDを取得します。
	 * </p>
	 * @return ルールID
	 */
	protected String getRuleId()
	{
		return RULE_ID;
	}

	/**
	 * <p>
	 * ルールエンジンを複数条件モードで実行するか設定します。
	 * </p>
	 * @return 複数条件モードで実行する場合はtrue
	 */
	protected boolean isMultiMode()
	{
		return true;
	}

	/**
	 * <p>
	 * キャンペーン開始コードを取得します。
	 * </p>
	 * @return キャンペーン開始コード
	 */
	public String getCampaign_sta_cd()
	{
		return campaign_sta_cd;
	}

	/**
	 * <p>
	 * キャンペーン開始コードを設定します。
	 * </p>
	 * @param campaign_sta_cd キャンペーン開始コード
	 */
	public void setCampaign_sta_cd(String campaign_sta_cd)
	{
		this.campaign_sta_cd = campaign_sta_cd;
	}

	/**
	 * <p>
	 * 割引登録年月日を取得します。
	 * </p>
	 * @return 割引登録年月日
	 */
	public String getWrib_add_ymd()
	{
		return wrib_add_ymd;
	}

	/**
	 * <p>
	 * 割引登録年月日を設定します。
	 * </p>
	 * @param wrib_add_ymd 割引登録年月日
	 */
	public void setWrib_add_ymd(String wrib_add_ymd)
	{
		this.wrib_add_ymd = wrib_add_ymd;
	}

	/**
	 * <p>
	 * 割引登録年月日当月1日を取得します。
	 * </p>
	 * @return 割引登録年月日当月1日
	 */
	public String getWrib_add_ymd_tg_one_day()
	{
		return wrib_add_ymd_tg_one_day;
	}

	/**
	 * <p>
	 * 割引登録年月日当月1日を設定する。
	 * </p>
	 * @param wrib_add_ymd_tg_one_day 割引登録年月日当月1日
	 */
	public void setWrib_add_ymd_tg_one_day(String wrib_add_ymd_tg_one_day)
	{
		this.wrib_add_ymd_tg_one_day = wrib_add_ymd_tg_one_day;
	}

	/**
	 * <p>
	 * 割引適用基準年月日を取得します。
	 * </p>
	 * @return 割引適用基準年月日
	 */
	public String getWrib_tekio_stdardymd()
	{
		return wrib_tekio_stdardymd;
	}

	/**
	 * <p>
	 * 割引適用基準年月日を設定します。
	 * </p>
	 * @param wrib_tekio_stdardymd 割引適用基準年月日
	 */
	public void setWrib_tekio_stdardymd(String wrib_tekio_stdardymd)
	{
		this.wrib_tekio_stdardymd = wrib_tekio_stdardymd;
	}

	/**
	 * <p>
	 * 割引サービス契約番号を取得します。
	 * </p>
	 * @return 割引サービス契約番号
	 */
	public String getWrib_svc_kei_no()
	{
		return wrib_svc_kei_no;
	}

	/**
	 * <p>
	 * 割引サービス契約番号を設定します。
	 * </p>
	 * @param wrib_tekio_stdardymd 割引サービス契約番号
	 */
	public void setWrib_svc_kei_no(String wrib_svc_kei_no)
	{
		this.wrib_svc_kei_no = wrib_svc_kei_no;
	}

	/**
	 * <p>
	 * 割引課金開始月指定コードを取得します。
	 * </p>
	 * @return 割引課金開始月指定コード
	 */
	public String getWrib_chrg_sta_mon_sti_cd()
	{
		return wrib_chrg_sta_mon_sti_cd;
	}

	/**
	 * <p>
	 * 割引課金開始月指定コードを設定します。
	 * </p>
	 * @param wrib_chrg_sta_mon_sti_cd 割引課金開始月指定コード
	 */
	public void setWrib_chrg_sta_mon_sti_cd(String wrib_chrg_sta_mon_sti_cd)
	{
		this.wrib_chrg_sta_mon_sti_cd = wrib_chrg_sta_mon_sti_cd;
	}

	/**
	 * <p>
	 * サービス課金開始年月日を算出します。
	 * </p>
	 * @return サービス課金開始年月日
	 * @throws ParseException 
	 */
	public String getWribAmntSnstStdardYmd() throws ParseException
	{
		//**********************************************************
		//* ＤＢ情報取得エリア                                     *
		//**********************************************************
		// 割引サービス契約のカレントレコードを取得します
		setKK0451CurrentData();

		//**********************************************************
		//* RULEパラメーター設定エリア                             *
		//**********************************************************
		// キャンペーン開始コードを設定します
		setCampaignStaCd();
		// 割引登録年月日を設定します
		setWribAddDay();
		// 割引課金開始月指定コードを設定します
		setWribChrgStaMonStiCd();

		// ルールエンジンパラメータの設定
		set(CAMPAIGN_STA_CD, getCampaign_sta_cd());						// キャンペーン開始コード
		set(WRIB_ADD_YMD, getWrib_add_ymd());							// 割引登録年月日
		set(WRIB_ADD_YMD_TG_ONE_DAY, getWrib_add_ymd_tg_one_day());		// 割引登録年月日当月1日		
		set(WRIB_CHRG_STA_MON_STI_CD, getWrib_chrg_sta_mon_sti_cd());	// 割引課金開始月指定コード
		set(WRIB_TEKIO_STDARDYMD, getWrib_tekio_stdardymd());			// 割引適用基準年月日

		// ルールエンジンの実行
		super.execRuleEngine();

		if (!hasNext())
		{
			return null;
		}

		// ルールエンジン実行の結果を返却
		HashMap<String, Object> map = getResultMap();
		return this.svcChrgStaYmdEdit((String)map.get(JUDGE_RSLT));
	}

	/**
	 * <p>
	 * 割引登録年月日と割引登録年月日当月1日を設定します
	 * </p>
	 * @throws ParseException 
	 */
	private void setWribAddDay() throws ParseException
	{
		// 割引サービス契約が未取得の場合
		if (kk0451Info == null)
		{
			return;
		}

		// 割引登録年月日が未設定の場合
		if (kk0451Info.isNull(KK0451ETMsg.WRIB_ADD_YMD))
		{
			return;
		}

		// 割引登録年月日を取得する
		String wribAddYmd = kk0451Info.getString(KK0451ETMsg.WRIB_ADD_YMD);

		// 割引登録年月日当月1日を作成
		String wribAddYmdMonth = wribAddYmd.substring(0, 6);
		String wribAddYmdOneDay = wribAddYmdMonth.concat("01");

		// 割引登録年月日を設定する
		setWrib_add_ymd(wribAddYmd);
		// 割引登録年月日当月1日を設定する
		setWrib_add_ymd_tg_one_day(wribAddYmdOneDay);
	}

	/**
	 * <p>
	 * 割引課金開始月指定コードを設定します。
	 * </p>
	 */
	private void setWribChrgStaMonStiCd()
	{
		// 割引サービス契約のカレントレコードが未取得の場合
		if (kk0451Info == null)
		{
			return;
		}

		// 割引課金開始月指定コードが未設定の場合
		if (kk0451Info.isNull(KK0451ETMsg.WRIB_CHRG_STA_MON_STI_CD))
		{
			return;
		}
		// 割引課金開始月指定コードを設定する
		setWrib_chrg_sta_mon_sti_cd(kk0451Info.getString(KK0451ETMsg.WRIB_CHRG_STA_MON_STI_CD));
	}
	
	/**
	 * <p>
	 * キャンペーン開始コードを設定します
	 * </p>
	 */
	private void setCampaignStaCd()
	{
		// 割引サービス契約内訳をサービス契約番号をkeyに検索
		JKKejbKK2361DBABase kk2361db = new JKKejbKK2361DBABase();
		CAANMsg[] kk2361msgList = kk2361db.getKK2361byWribSvcKei(getWrib_svc_kei_no(), null, JKKModelCommon.getOpeDate(inCBSMsg));

		// 検索結果が0件の場合
		if (kk2361msgList == null)
		{
			return;
		}
		
		ArrayList<String> alist = new ArrayList<String>();
		ArrayList<String> campStaCdList = new ArrayList<String>();
		String campaignStaCd = null;

		for (CAANMsg kk2361info : kk2361msgList)
		{			
			// 一回出てきた割引サービス詳細コードは検索せず
			if (alist.contains(kk2361info.getString(KK2361ETMsg.WRIB_SVC_DTL_CD)))
			{
				continue;
			}
			// 割引サービス詳細コードをためる
			alist.add(kk2361info.getString(KK2361ETMsg.WRIB_SVC_DTL_CD));

			// 割引サービス詳細のカレント検索
			CAANMsg kk2371ETMsg = new CAANMsg(KK2371ETMsg.class.getName());
			kk2371ETMsg.set(KK2371ETMsg.WRIB_SVC_DTL_CD, kk2361info.getString(KK2361ETMsg.WRIB_SVC_DTL_CD));
			kk2371ETMsg.set(KK2371ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(kk2371ETMsg));

			CAANMsg kk2371info = new JKKejbKK2371DBABase().findByCurrent(kk2371ETMsg);


			// 割引サービス詳細が見つからなかった場合
			if (kk2371info == null)
			{
				continue;
			}

			// キャンペーン開始コードを取得する
			campaignStaCd = kk2371info.getString(KK2371ETMsg.CAMPAIGN_STA_CD);

			// キャンペーン開始コードが違うものがきたら
			if (campStaCdList.size() != 0 && !campStaCdList.contains(campaignStaCd))
			{
				throw new CAANRuntimeException("キャンペーン開始コードが異なる契約があります。");
			}
			// キャンペーン開始コードをためる
			campStaCdList.add(campaignStaCd);
		}
		setCampaign_sta_cd(campaignStaCd);
	}

	/**
	 * <p>
	 * サービス課金開始年月日を算出します
	 * </p>
	 * @param result RULE結果
	 * @return サービス課金開始年月日
	 * @throws ParseException 
	 */
	private String svcChrgStaYmdEdit(String result) throws ParseException
	{
		// ルール結果が未設定、空白の場合
		if (result == null || result.isEmpty())
		{
			return null;
		}
		
		String svcChrgStaYmd = null;

		// "割引適用基準年月日"の場合
		if (JUDGE_RSLT_WRIB_TEKIO_STDARDYMD.equals(result))
		{
			svcChrgStaYmd = getWrib_tekio_stdardymd(); 
		}
		// "割引登録年月日の翌月1日"の場合
		else if (JUDGE_RSLT_WRIB_ADD_YMD_YKGTU_FIRST.equals(result))
		{
			String addMonth = JKKModelCommon.addMonth(getWrib_add_ymd(), 1);
			String ym = addMonth.substring(0, 6);
			svcChrgStaYmd = ym.concat("01");
		}
		// "割引登録年月日の前月1日"の場合
		else if (JUDGE_RSLT_WRIB_ADD_YMD_ZNGTU_FIRST.equals(result))
		{
			String subTractMonth = JKKModelCommon.addMonth(getWrib_add_ymd(), -1);
			String ym = subTractMonth.substring(0, 6);
			svcChrgStaYmd = ym.concat("01");
		}
		// "割引登録年月日の当月1日"の場合
		else if (JUDGE_RSLT_WRIB_ADD_YMD_TOGTU_FIRST.equals(result))
		{
			String ym = getWrib_add_ymd().substring(0, 6);
			svcChrgStaYmd = ym.concat("01");
		}
		// "割引適用基準年月日の当月1日"の場合
		else if (JUDGE_RSLT_WRIB_TEKIO_STDARDYMD_TOGTU_FIRST.equals(result))
		{
			String ym = getWrib_tekio_stdardymd().substring(0, 6);
			svcChrgStaYmd = ym.concat("01");
		}
		// "割引適用基準年月日の翌月1日"の場合
		else if (JUDGE_RSLT_WRIB_TEKIO_STDARDYMD_NEMO_FIRST.equals(result))
		{
			String nextymd = JKKModelCommon.addMonth(getWrib_tekio_stdardymd(), 1);
			String ym = nextymd.substring(0, 6);
			svcChrgStaYmd = ym.concat("01");
		}
		// "上記以外"の場合
		else if (JUDGE_RSLT_NOT_SET.equals(result))
		{
			return null;
			// 想定外の場合
		}
		else
		{
			throw new CAANRuntimeException("RULE0089002が想定外の結果を返却しました。");
		}
		return svcChrgStaYmd;
	}
	
	/**
	 * <p>
	 * 割引サービス契約番号に紐付いた割引サービス契約のカレントレコードを取得します。
	 * </p>
	 */
	private void setKK0451CurrentData()
	{
		// 割引サービス契約のカレントレコードを取得する
		CAANMsg kk0451msg = new CAANMsg(KK0451ETMsg.class.getName());
		kk0451msg.set(KK0451ETMsg.WRIB_SVC_KEI_NO, getWrib_svc_kei_no());
		kk0451msg.set(KK0451ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(kk0451msg));

		kk0451Info = new JKKejbKK0451DBABase().findByCurrent(kk0451msg);
	}
}
