/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbRule0091001
*	ソースファイル名：JKKejbRule0091001.java
*	作成者			：富士通
*	日付			：2013年11月01日
*＜機能概要＞
*	課金開始日（機器オプションサービス契約）相関ルール部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v7.00.00	2013/11/01	FJ）河井	新規作成
*
**********************************************************************/

package eo.ejb.common.rule;

import java.text.ParseException;
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.JSYejbLog;

import eo.ejb.common.JKKModelCommon;

/**
 * <p>
 * 課金開始日（機器オプションサービス契約）相関ルール部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbRule0091001 extends JKKejbRuleBase
{
	/** ルールID */
	private static final String RULE_ID = "RULE0091001";

	/** 機器オプションサービスコード */
	private static final String KKOP_SVC_CD = "KKOP_SVC_CD";

	/** 異動区分 */
	private static final String IDO_DIV = "IDO_DIV";

	/** 更新契機 */
	private static final String UPD_OPTY = "UPD_OPTY";

	/** 解約時課金 */
	private static final String DSL_JI_CHRG = "DSL_JI_CHRG";

	/** 課金開始前／開始後 */
	private static final String CHRG_STA_ZENGO = "CHRG_STA_ZENGO";

	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** 機器オプションサービスコード */
	private String kkop_svc_cd = null;

	/** 異動区分 */
	private String ido_div = null;

	/** 更新契機 */
	private String upd_opty = null;

	/** 解約時課金 */
	private String dsl_ji_chrg = null;

	/** 課金開始前／開始後 */
	private String chrg_sta_zengo = null;

	/** 基準日 */
	public static final String STD_DT = "STD_DT";

	/** 基準日からの相対日 */
	public static final String RELATIVE_DATE_COUNT = "RELATIVE_DATE_COUNT";

	/** 実日／営業日 */
	public static final String COUNT_METHOD = "COUNT_METHOD";
	
	/** 基準日(機器オプションサービス契約.サービス開始日) */
	public static final String STD_DT_KK2811_SVC_STA = "1";

	/** 基準日(機器オプションサービス契約.サービス課金開始日) */
	public static final String STD_DT_KK2811_SVC_CHRG_STA = "2";

	/** 基準日(サービス契約.サービス契約の課金開始年月日) */
	public static final String STD_DT_KK2811_BEF_SVC_STA = "3";

	/** 基準日(機器オプションサービス契約.サービス終了年月日) */
	public static final String STD_DT_KK2811_SVC_END = "4";
	
	
	/** 基準日からの相対日(+0) */
	public static final String RELATIVE_DATE_NO_COUNT = "0";

	/** 基準日からの相対日(翌月月初) */
	public static final String RELATIVE_DATE_COUNT_NEXT = "1";

	/** 月初設定用 */
	public static final String GESYO_SETTEI = "01";
	
	/** サービス開始年月日 */
	private String kk2811_svc_sta_ymd = null;

	/** サービス課金開始年月日 */
	private String kk2811_svc_chrg_sta_ymd = null;

	/** サービス終了年月日 */
	private String kk2811_svc_end_ymd = null;
	
	/** 元のサービス契約の課金開始年月日 */
	private String kk0081_svc_chrg_sta_ymd = null;
	
	

	/**
	 * <p>
	 * JKKejbRule0091001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0091001(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 機器オプションサービスコード
	 */
	private String getKkop_svc_cd()
	{
		return this.kkop_svc_cd;
	}

	/**
	 * <p>
	 * 異動区分を取得します。
	 * </p>
	 * @return 異動区分
	 */
	private String getIdo_div()
	{
		return this.ido_div;
	}

	/**
	 * <p>
	 * 更新契機を取得します。
	 * </p>
	 * @return 更新契機
	 */
	private String getUpd_opty()
	{
		return this.upd_opty;
	}

	/**
	 * <p>
	 * 解約時課金を取得します。
	 * </p>
	 * @return 解約時課金
	 */
	private String getDsl_ji_chrg()
	{
		return this.dsl_ji_chrg;
	}

	/**
	 * <p>
	 * 課金開始前／開始後を取得します。
	 * </p>
	 * @return 課金開始前／開始後
	 */
	private String getChrg_sta_zengo()
	{
		return this.chrg_sta_zengo;
	}

	/**
	 * <p>
	 * 機器オプションサービスコードを設定します。
	 * </p>
	 * @param p_kkop_svc_cd 機器オプションサービスコード
	 */
	public void setKkop_svc_cd(String p_kkop_svc_cd)
	{
		this.kkop_svc_cd = p_kkop_svc_cd;
	}

	/**
	 * <p>
	 * 異動区分を設定します。
	 * </p>
	 * @param p_ido_div 異動区分
	 */
	public void setIdo_div(String p_ido_div)
	{
		this.ido_div = p_ido_div;
	}

	/**
	 * <p>
	 * 更新契機を設定します。
	 * </p>
	 * @param p_upd_opty 更新契機
	 */
	public void setUpd_opty(String p_upd_opty)
	{
		this.upd_opty = p_upd_opty;
	}

	/**
	 * <p>
	 * 解約時課金を設定します。
	 * </p>
	 * @param p_dsl_ji_chrg 解約時課金
	 */
	public void setDsl_ji_chrg(String p_dsl_ji_chrg)
	{
		this.dsl_ji_chrg = p_dsl_ji_chrg;
	}

	/**
	 * <p>
	 * 課金開始前／開始後を設定します。
	 * </p>
	 * @param p_chrg_sta_zengo 課金開始前／開始後
	 */
	public void setChrg_sta_zengo(String p_chrg_sta_zengo)
	{
		this.chrg_sta_zengo = p_chrg_sta_zengo;
	}

	/**
	 * <p>
	 * サービス開始年月日を取得します。
	 * </p>
	 * @return サービス開始年月日
	 */
	private String getKK2811Svc_sta_ymd()
	{
		return this.kk2811_svc_sta_ymd;
	}
	
	/**
	 * <p>
	 * サービス課金開始年月日を設定します。
	 * </p>
	 * @param p_svc_sta_ymd サービス課金開始年月日
	 */
	public String getKK2811Svc_chrg_sta_ymd()
	{
		return kk2811_svc_chrg_sta_ymd;
	}
	

	/**
	 * <p>
	 * サービス終了年月日を取得します。
	 * </p>
	 * @return サービス終了年月日
	 */
	public String getKK2811Svc_end_ymd()
	{
		return kk2811_svc_end_ymd;
	}

	/**
	 * <p>
	 * 元のサービス契約の課金開始年月日を取得します。
	 * </p>
	 * @return 元のサービス契約の課金開始年月日
	 */
	public String getKK0081_svc_chrg_sta_ymd()
	{
		return kk0081_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * サービス開始年月日を設定します。
	 * </p>
	 * @param kk2811_p_svc_sta_ymd サービス開始年月日
	 */
	public void setKK2811Svc_sta_ymd(String kk2811_p_svc_sta_ymd)
	{
		this.kk2811_svc_sta_ymd = kk2811_p_svc_sta_ymd;
	}

	/**
	 * <p>
	 * サービス課金開始年月日を設定します。
	 * </p>
	 * @param kk2811_p_svc_chrg_sta_ymd サービス課金開始年月日
	 */
	public void setKK2811Svc_chrg_sta_ymd(String kk2811_p_svc_chrg_sta_ymd)
	{
		this.kk2811_svc_chrg_sta_ymd = kk2811_p_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * サービス終了年月日を設定します。
	 * </p>
	 * @param kk2811_p_svc_end_ymd サービス終了年月日
	 */
	public void setKK2811Svc_end_ymd(String kk2811_p_svc_end_ymd)
	{
		this.kk2811_svc_end_ymd = kk2811_p_svc_end_ymd;
	}

	/**
	 * <p>
	 * 元のサービス契約の課金開始年月日を設定します。
	 * </p>
	 * @param 元のサービス契約の課金開始年月日
	 */
	public void setKK0081_svc_chrg_sta_ymd(String kk0081_p_svc_chrg_sta_ymd)
	{
		kk0081_svc_chrg_sta_ymd = kk0081_p_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * 課金開始日（機器オプションサービス契約）相関ルールを実行し、実行結果を取得します。
	 * </p>
	 * @return ルールエンジンの実行結果
	 */
	public HashMap<String, Object> referRuleEngine()
	{
		// ログ出力
		execLogOutput();

		// ルールエンジンで使用する値を設定
		set(KKOP_SVC_CD, getKkop_svc_cd());
		set(IDO_DIV, getIdo_div());
		set(UPD_OPTY, getUpd_opty());
		set(DSL_JI_CHRG, getDsl_ji_chrg());
		set(CHRG_STA_ZENGO, getChrg_sta_zengo());

		// ルールエンジンの実行
		super.execRuleEngine();

		if (!hasNext())
		{
			// 実行結果が存在しない場合
			return null;
		}

		// 実行結果を返却
		return getResultMap();
	}

	/**
	 * <p>
	 * メンバ変数のログ出力を行う。
	 * </p>
	 */
	private void execLogOutput()
	{
		// 機器オプションサービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0091001.kkop_svc_cd=" + getKkop_svc_cd());
		// 異動区分
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0091001.ido_div=" + getIdo_div());
		// 更新契機
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0091001.upd_opty=" + getUpd_opty());
		// 解約時課金
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0091001.dsl_ji_chrg=" + getDsl_ji_chrg());
		// 課金開始前／開始後
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0091001.chrg_sta_zengo=" + getChrg_sta_zengo());
	}
	/**
	 * <p>
	 * 相関ルールの結果により取得した課金開始年月日を算出します。
	 * </p>
	 * @return 算出した課金開始年月日を返却
	 */
	public String getChrgStaYmd()
	{

		String ymd = null;
		
		// ルールエンジンで使用する値を設定
		set(KKOP_SVC_CD, getKkop_svc_cd());
		set(IDO_DIV, getIdo_div());
		set(UPD_OPTY, getUpd_opty());
		set(DSL_JI_CHRG, getDsl_ji_chrg());
		set(CHRG_STA_ZENGO, getChrg_sta_zengo());

		// ログ出力
		execLogOutput();
		
		// ルールエンジンの実行
		super.execRuleEngine();
		
		// 実行結果が存在しない場合、nullを返す。
		if (!hasNext())
		{
			return ymd;
		}

		// ルールエンジンの実行結果を取得
		HashMap<String, Object> retMap = getResultMap();

		// 実行結果の基準日が「サービス開始年月日」の場合
		if (STD_DT_KK2811_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス開始年月日」を基準日とする
			ymd = getYmd(retMap, getKK2811Svc_sta_ymd());
		}
		// 実行結果の基準日が「サービス課金開始年月日」の場合
		else if (STD_DT_KK2811_SVC_CHRG_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス課金開始年月日」を基準日とする
			ymd = getYmd(retMap, getKK2811Svc_chrg_sta_ymd());
		}
		// 実行結果の基準日が「サービス終了年月日」の場合
		else if (STD_DT_KK2811_SVC_END.equals(retMap.get(STD_DT)))
		{
			// 「サービス終了年月日」を基準日とする
			ymd = getYmd(retMap, getKK2811Svc_end_ymd());
		}
		// 実行結果の基準日が「元のサービス契約の課金開始年月日」の場合
		else if (STD_DT_KK2811_BEF_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 「元のサービス契約の課金開始年月日」とする
			ymd = getYmd(retMap, getKK0081_svc_chrg_sta_ymd());
		}

		return ymd;
	}

	/**
	 * <p>
	 * 課金開始年月日を算出します。
	 * </p>
	 * @param retMap ルールの結果
	 * @param stdardDay 基準日
	 * @return 算出した課金開始年月日
	 */
	private String getYmd(HashMap<String, Object> retMap, String stdardDay)
	{
		// 基準日がnullの場合
		if(stdardDay == null) {
			return null;
		}
		
		// 基準日からの相対日が"+0"の場合
		if (RELATIVE_DATE_NO_COUNT.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日を「課金開始日」とする
			return stdardDay;
		}

		// 基準日からの相対日が"翌月月初"の場合
		else if (RELATIVE_DATE_COUNT_NEXT.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日の翌月を算出する
			String ymd = null;

			try
			{
				ymd = JKKModelCommon.addMonth(stdardDay, 1);
			}
			catch (ParseException ce)
			{
				throw new CAANRuntimeException(ce);
			}

			// 年月を抽出し、1日に設定する
			String ym = ymd.substring(0, 6);
			ymd = ym + GESYO_SETTEI;

			// 基準日の翌月1日を「課金開始日」とする
			return ymd;
		}
		
		// 基準日からの相対日が設定されないのは電話サービスのプラン課金開始日の場合のみ
		return stdardDay;
	}
}
