/*********************************************************************
 *	All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *	システム名		：eo顧客基幹システム
 *	モジュール名	：JKKejbRule0066001
 *	ソースファイル名：JKKejbRule0066001.java
 *	作成者			：富士通
 *	日付			：2011年11月10日
 *＜機能概要＞
 *	課金開始日設定(オプション)相関ルール部品
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *	v1.00.00	2011/11/10	FJ)			新規作成
*	v8.00.00	2014/03/11	FJ)寺園		ANK-1855-00-00
 *	v8.00.01	2014/04/29	FJ)宇野		OM-2014-0001529、OM-2014-0001536
 *  v39.00.00   2018/10/01  FJ)舘山		【ANK-3484-00-00】_端末補償サービス導入対応
 **********************************************************************/

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 JKKejbRule0066001 extends JKKejbRuleBase
{

	/** ルールID */
	private static final String RULE_ID = "RULE0066001";

	/** サービスコード */
	public static final String SVC_CD = "SVC_CD";

	/** 異動区分 */
	public static final String IDO_DIV = "IDO_DIV";

	/** オプションサービスコード */
	public static final String OP_SVC_CD = "OP_SVC_CD";

	/** 開始日 */
	public static final String STA_DAY = "STA_DAY";

	/** 更新契機 */
	public static final String UP_OPTY = "UP_OPTY";

	/** 解約時課金 */
	public static final String DSLJI_CHRG = "DSLJI_CHRG";

	/** 課金開始前／開始後 */
	public static final String DSL_STA_ZENGO = "DSL_STA_ZENGO";

	/** 元のサービス契約の料金グループ */
	public static final String PRC_GRP_CD = "PRC_GRP_CD";

// ▽▽▽ ANK-3484-00-00 ADD START

	/** サービス開始年月 */
	public static final String SVC_STA_YM = "SVC_STA_YM";
	
	/** 引継元サービス課金終了年月 */
	public static final String HKTGMT_SVC_CHRG_ENDYM = "HKTGMT_SVC_CHRG_ENDYM";
	
// △△△ ANK-3484-00-00 ADD END

	/** 申込期間 */
	public static final String MSKM_PRD = "MSKM_PRD";

	/** 請求年月の末日以前／以降 */
	public static final String SEIKYU_YM_ZENGO = "SEIKYU_YM_ZENGO";

	/** 基準日 */
	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";

	/** 開始日(1日以外) */
	public static final String STA_YMD_OTHER = "0";

	/** 開始日(1日) */
	public static final String STA_YMD_ONE = "1";

	/** 基準日(サービス開始日) */
	public static final String STD_DT_KK0351_SVC_STA = "1";

	/** 基準日(サービス課金開始日) */
	public static final String STD_DT_KK0351_SVC_CHRG_STA = "2";

	/** 基準日(サービス終了日) */
	public static final String STD_DT_KK0351_SVC_END = "3";

	/** 基準日(元のサービス契約の課金開始年月日) */
	public static final String STD_DT_KK0351_BEF_SVC_STA = "4";
	
// ▽▽▽ ANK-3484-00-00 ADD START
	
	/** 基準日(元のサービス契約の課金終了年月日) */
	public static final String STD_DT_KK0351_BEF_SVC_CHRG_END = "5";
	
// △△△ ANK-3484-00-00 ADD END
	
	/** 基準日からの相対日(+0) */
	public static final String RELATIVE_DATE_COUNT_0 = "0";

	/** 基準日からの相対日(当月月初) */
	public static final String RELATIVE_DATE_COUNT_TOGETSU = "1";

	/** 基準日からの相対日(翌月月初) */
	public static final String RELATIVE_DATE_COUNT_NEXT = "2";

	/** 基準日からの相対日(月初または翌月月初) */
	public static final String RELATIVE_DATE_COUNT_01_NEXT = "3";

	/** 月初設定用 */
	public static final String GESYO_SETTEI = "01";

	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** サービスコード */
	private String svc_cd = null;

	/** 異動区分 */
	private String ido_div = null;

	/** オプションサービスコード */
	private String op_svc_cd = null;

	/** サービス開始年月日 */
	private String svc_sta_ymd = null;

	/** サービス課金開始年月日 */
	private String svc_chrg_sta_ymd = null;

	/** サービス終了年月日 */
	private String svc_end_ymd = null;

	/** 更新契機 */
	private String upd_type = null;

	/** 契約時課金 */
	private String dslji_chrg = null;
	
	/** 課金開始前／開始後 */
	private String dsl_sta_zengo = null;

	/** 元のサービス契約の料金グループ */
	private String prc_grp_cd = null;

	/** 申込期間 */
	private String mskm_period = null;

	/** 元のサービス契約の課金開始年月日 */
	private String befor_svc_chrg_sta_ymd = null;

	/** 請求年月の末日以前／以降 */
	private String seikyu_ym_zengo = null;

// ▽▽▽ ANK-3484-00-00 ADD START
	
	/** 基準日(元のサービス契約の課金終了年月日) */
	private String befor_svc_chrg_end_ymd = null;
	
// △△△ ANK-3484-00-00 ADD END
	
	/**
	 * <p>
	 * JKKejbRule0066001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0066001(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 getSvc_cd()
	{
		return this.svc_cd;
	}

	/**
	 * <p>
	 * 異動区分を取得します。
	 * </p>
	 * @return 異動区分
	 */
	private String getIdo_div()
	{
		return this.ido_div;
	}

	/**
	 * <p>
	 * オプションサービスコードを取得します。
	 * </p>
	 * @return オプションサービスコード
	 */
	private String getOp_svc_cd()
	{
		return this.op_svc_cd;
	}

	/**
	 * <p>
	 * サービス開始年月日を取得します。
	 * </p>
	 * @return サービス開始年月日
	 */
	private String getSvc_sta_ymd()
	{
		return this.svc_sta_ymd;
	}
	
	/**
	 * <p>
	 * サービス課金開始年月日を設定します。
	 * </p>
	 * @param p_svc_sta_ymd サービス課金開始年月日
	 */
	public String getSvc_chrg_sta_ymd()
	{
		return svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * サービス終了年月日を取得します。
	 * </p>
	 * @return サービス終了年月日
	 */
	public String getSvc_end_ymd()
	{
		return svc_end_ymd;
	}

	/**
	 * <p>
	 * 更新契機を取得します。
	 * </p>
	 * @return 更新契機
	 */
	public String getUpd_type()
	{
		return upd_type;
	}

	/**
	 * <p>
	 * 解約時課金を取得します。
	 * </p>
	 * @return 解約時課金
	 */
	public String getDslji_chrg()
	{
		return dslji_chrg;
	}

	/**
	 * <p>
	 * 課金開始前／開始後を取得します。
	 * </p>
	 * @return 課金開始前／開始後
	 */
	public String getDsl_sta_zengo()
	{
		return dsl_sta_zengo;
	}

	/**
	 * <p>
	 * 元のサービス契約の料金グループを取得します。
	 * </p>
	 * @return 元のサービス契約の料金グループ
	 */
	public String getPrc_grp_cd()
	{
		return prc_grp_cd;
	}

	/**
	 * <p>
	 * 申込期間を取得します。
	 * </p>
	 * @return 申込期間
	 */
	public String getMskm_period()
	{
		return mskm_period;
	}
	
	/**
	 * <p>
	 * 元のサービス契約の課金開始年月日を取得します。
	 * </p>
	 * @return 元のサービス契約の課金開始年月日
	 */
	public String getBefor_svc_chrg_sta_ymd()
	{
		return befor_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * 請求年月の末日以前／以降を取得します。
	 * </p>
	 * @return 請求年月の末日以前／以降
	 */
	public String getSeikyu_Ym_Zengo()
	{
		return this.seikyu_ym_zengo;
	}

	/**
	 * <p>
	 * サービスコードを設定します。
	 * </p>
	 * @param p_svc_cd サービスコード
	 */
	public void setSvc_cd(String p_svc_cd)
	{
		this.svc_cd = p_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_op_svc_cd オプションサービスコード
	 */
	public void setOp_svc_cd(String p_op_svc_cd)
	{
		this.op_svc_cd = p_op_svc_cd;
	}

	/**
	 * <p>
	 * サービス開始年月日を設定します。
	 * </p>
	 * @param p_svc_sta_ymd サービス開始年月日
	 */
	public void setSvc_sta_ymd(String p_svc_sta_ymd)
	{
		this.svc_sta_ymd = p_svc_sta_ymd;
	}

	/**
	 * <p>
	 * サービス課金開始年月日を設定します。
	 * </p>
	 * @param p_svc_chrg_sta_ymd サービス課金開始年月日
	 */
	public void setSvc_chrg_sta_ymd(String p_svc_chrg_sta_ymd)
	{
		this.svc_chrg_sta_ymd = p_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * サービス終了年月日を設定します。
	 * </p>
	 * @param p_svc_end_ymd サービス終了年月日
	 */
	public void setSvc_end_ymd(String p_svc_end_ymd)
	{
		this.svc_end_ymd = p_svc_end_ymd;
	}

	/**
	 * <p>
	 * 更新契機を設定します。
	 * </p>
	 * @param p_upd_type 更新契機
	 */
	public void setUpd_type(String p_upd_type)
	{
		this.upd_type = p_upd_type;
	}

	/**
	 * <p>
	 * 契約時課金を設定します。
	 * </p>
	 * @param p_dslji_chrg　契約時課金
	 */
	public void setDslji_chrg(String p_dslji_chrg)
	{
		this.dslji_chrg = p_dslji_chrg;
	}

	/**
	 * <p>
	 * 課金開始前／開始後を設定します。
	 * </p>
	 * @param p_dsl_sta_zengo 課金開始前／開始後
	 */
	public void setDsl_sta_zengo(String p_dsl_sta_zengo)
	{
		this.dsl_sta_zengo = p_dsl_sta_zengo;
	}
	
	/**
	 * <p>
	 * 元のサービス契約の料金グループを設定します。
	 * </p>
	 * @param p_prc_grp_cd 元のサービス契約の料金グループ
	 */
	public void setPrc_grp_cd(String p_prc_grp_cd)
	{
		this.prc_grp_cd = p_prc_grp_cd;
	}
	
	/**
	 * <p>
	 * 申込期間を設定します。
	 * </p>
	 * @param p_mskm_period 申込期間
	 */
	public void setMskm_period(String p_mskm_period)
	{
		this.mskm_period = p_mskm_period;
	}

	/**
	 * <p>
	 * 元のサービス契約の課金開始年月日を設定します。
	 * </p>
	 * @param 元のサービス契約の課金開始年月日
	 */
	public void setBefor_svc_chrg_sta_ymd(String p_befor_svc_chrg_sta_ymd)
	{
		this.befor_svc_chrg_sta_ymd = p_befor_svc_chrg_sta_ymd;
	}

	/**
	 * <p>
	 * 請求年月の末日以前／以降を設定します。
	 * </p>
	 * @param p_seikyu_ym_zengo 請求年月の末日以前／以降
	 */
	public void setSeikyu_Ym_Zengo(String p_seikyu_ym_zengo)
	{
		this.seikyu_ym_zengo = p_seikyu_ym_zengo;
	}

	/**
	 * <p>
	 * 相関ルールの結果により取得した課金開始年月日を算出します。
	 * </p>
	 * @return 算出した課金開始年月日を返却
	 */
	public String getChrgStaYmd()
	{
		// ログ出力
		execLogOutput();

		String ymd = null;

		// ルールエンジンで使用する値を設定
		set(SVC_CD, getSvc_cd());
		set(IDO_DIV, getIdo_div());
		set(UP_OPTY, getUpd_type());
		set(OP_SVC_CD, getOp_svc_cd());
		set(PRC_GRP_CD, getPrc_grp_cd());
		set(MSKM_PRD, getMskm_period());
		set(DSLJI_CHRG, getDslji_chrg());
		set(DSL_STA_ZENGO, getDsl_sta_zengo());
		set(SEIKYU_YM_ZENGO, getSeikyu_Ym_Zengo());
// ▽▽▽ ANK-3484-00-00 ADD START
		// サービス開始日の年月を設定
		if (getSvc_sta_ymd() != null && getSvc_sta_ymd().length() > 6)
		{
			set(SVC_STA_YM, getSvc_sta_ymd().substring(0, 6));
		}
		// 引継元のサービス課金終了日を設定
		if (getBefor_svc_chrg_end_ymd() != null && getBefor_svc_chrg_end_ymd().length() > 6)
		{
			set(HKTGMT_SVC_CHRG_ENDYM, getBefor_svc_chrg_end_ymd().substring(0, 6));
		}
// △△△ ANK-3484-00-00 ADD END

		// ルールエンジンの実行
		super.execRuleEngine();

		// 実行結果が存在しない場合、nullを返す。
		if (!hasNext())
		{
			return ymd;
		}

		// ルールエンジンの実行結果を取得
		HashMap<String, Object> retMap = getResultMap();

		// 実行結果の基準日が「サービス開始年月日」の場合
		if (STD_DT_KK0351_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス開始年月日」を基準日とする
			ymd = getYmd(retMap, getSvc_sta_ymd());
		}
		// 実行結果の基準日が「サービス課金開始年月日」の場合
		else if (STD_DT_KK0351_SVC_CHRG_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス課金開始年月日」を基準日とする
			ymd = getYmd(retMap, getSvc_chrg_sta_ymd());
		}
		// 実行結果の基準日が「サービス終了年月日」の場合
		else if (STD_DT_KK0351_SVC_END.equals(retMap.get(STD_DT)))
		{
			// 「サービス終了年月日」を基準日とする
			ymd = getYmd(retMap, getSvc_end_ymd());
		}
		// 実行結果の基準日が「元のサービス契約の課金開始年月日」の場合
		else if (STD_DT_KK0351_BEF_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス終了年月日」を基準日とする
			ymd = getYmd(retMap, getBefor_svc_chrg_sta_ymd());
		}
// ▽▽▽ ANK-3484-00-00 ADD START
		// 実行結果の基準日が「引継元のオプションサービス契約の課金終了年月日」の場合
		else if (STD_DT_KK0351_BEF_SVC_CHRG_END.equals(retMap.get(STD_DT)))
		{
			// 「サービス課金終了年月日」を基準日とする
			ymd = getYmd(retMap, getBefor_svc_chrg_end_ymd());
		}
		
// △△△ ANK-3484-00-00 ADD END 
		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_COUNT_0.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日を「課金開始日」とする
			return stdardDay;
		}
		
		// 基準日からの相対日が"当月月初"の場合
		else if (RELATIVE_DATE_COUNT_TOGETSU.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 年月を抽出し、1日に設定する
			String ym = stdardDay.substring(0, 6);
			String ymd = ym + GESYO_SETTEI;

			// 基準日の当月1日を「課金開始日」とする
			return ymd;
		}

		// 基準日からの相対日が"翌月月初"の場合
		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;
		}

		// 基準日からの相対日が"月初"または"翌月月初"の場合
		else if (RELATIVE_DATE_COUNT_01_NEXT.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日が月初の場合、相対日を"+0"とする
			if ("01".equals(stdardDay.substring(6, 8)))
			{
				return stdardDay;
			}

			// 基準日の翌月を算出する
			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 null;
	}

	/**
	 * <p>
	 * メンバ変数のログ出力を行う。
	 * </p>
	 */
	private void execLogOutput()
	{
		// サービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.svc_cd=" + getSvc_cd());
		// 異動区分
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.ido_div=" + getIdo_div());
		// 更新契機
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.upd_type=" + getUpd_type());
		// オプションサービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.op_svc_cd=" + getOp_svc_cd());
		// 元のサービス契約の料金グループ
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.prc_grp_cd=" + getPrc_grp_cd());
		// 申込期間
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.mskm_period=" + getMskm_period());
		// 解約時課金
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.dslji_chrg=" + getDslji_chrg());
		// 課金開始前／開始後
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.dsl_sta_zengo=" + getDsl_sta_zengo());
		// 請求年月の末日以前／以降
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.seikyu_ym_zengo=" + getSeikyu_Ym_Zengo());
// ▽▽▽ ANK-3484-00-00 ADD START
		// サービス開始日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.svc_sta_ymd=" + getSvc_sta_ymd());
		// 引継元のサービス課金終了日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0066001.hktgmt_svc_chrg_endymd=" + getBefor_svc_chrg_end_ymd());
// △△△ ANK-3484-00-00 ADD END
	}
// ▽▽▽ ANK-3484-00-00 ADD START
	/**
	 * 引継元のサービス課金終了日を返す。
	 * <p>
	 * @return サービス課金終了日
	 */
	private String getBefor_svc_chrg_end_ymd()
	{
		return befor_svc_chrg_end_ymd;
	}
	/**
	 * 引継元のサービス課金終了日を設定する。
	 * <p>
	 * @param サービス課金終了日
	 */
	public void setBefor_svc_chrg_end_ymd(String befor_svc_chrg_end_ymd)
	{
		this.befor_svc_chrg_end_ymd = befor_svc_chrg_end_ymd;
	}
// △△△ ANK-3484-00-00 ADD END
}
