/*********************************************************************
 *	All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *	システム名		：eo顧客基幹システム
 *	モジュール名	：JKKejbRule0074001
 *	ソースファイル名：JKKejbRule0074001.java
 *	作成者			：富士通
 *	日付			：2011年11月10日
 *＜機能概要＞
 *	開始日設定(オプションサービス)相関ルール部品
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *	v1.00.00	2011/11/10	FJ)			新規作成
 *	v8.00.00	2014/04/29	FJ）宇野	OM-2014-0001529、OM-2014-0001536
 *  v39.00.00   2018/10/01  FJ)舘山		【ANK-3484-00-00】_端末補償サービス導入対応
 *  v50.00.00	2020/06/12  FJ) 西窪    【ANK-3754-00-00】トビラフォン対応
 **********************************************************************/

package eo.ejb.common.rule;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
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.common.util.JPCDateUtil;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0361C040CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0081DBABase;
import eo.ejb.common.db.JKKejbKK0351DBABase;

/**
 * <p>
 * 開始日設定(オプションサービス)相関ルール部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbRule0074001 extends JKKejbRuleBase
{

	/** ルールID */
	private static final String RULE_ID = "RULE0074001";

	/** サービスコード */
	public static final String SVC_CD = "SVC_CD";

	/** オプションサービスコード */
	public static final String OP_SVC_CD = "OP_SVC_CD";

	/** 異動区分 */
	public static final String IDO_KBN = "IDO_KBN";

	/** 申込期間 */
	public static final String MSKM_PRD = "MSKM_PRD";

	/** 即時／翌月 */
	public static final String SKJ_YKJT = "SKJ_YKJT";

	/** 元のサービス契約のサービス開始日 */
	public static final String KK0081_SVC_STA_YMD = "KK0081_SVC_STA_YMD";

	/** 元のサービス契約の料金グループ */
	public static final String PRC_GRP_CD = "PRC_GRP_CD";

	// ▽▽▽ ANK-3754-00-00 ADD STRAT
	/** 工事会社配送フラグ */
	public static final String KOCHAI_FLG = "KOCHAI_FLG";
	// △△△ ANK-3754-00-00 ADD END

	/** 基準日 */
	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 PRIORITY_STD_DT = "PRIORITY_STD_DT";

	/** 元のサービス契約のサービス開始日(1〜15日) */
	public static final String KK0081_SVC_STA_FIRST = "1";

	/** 元のサービス契約のサービス開始日(16〜末日) */
	public static final String KK0081_SVC_STA_SECOND = "2";

	/** 基準日(元のサービス契約のサービス開始日) */
	public static final String STD_DT_KK0081_SVC_STA = "1";

	/** 基準日(申込.申込受付年月日) */
	public static final String STD_DT_KK0011_MSKM_UK = "2";

	/** 基準日(バッチ運用日) */
	public static final String STD_DT_BAT_OPE = "3";

	/** 基準日(NHK指定の開始日) */
	public static final String STD_DT_NHK_STA = "4";

	/** 基準日(入力値.サービス開始年月日) */
	public static final String STD_DT_INPUT = "5";
	
	/** 基準日(料金計算日より求めた請求年月の末日) */
	public static final String STD_DT_CH0501_SEIKY_YMD = "6";

// ▽▽▽ ANK-3484-00-00 ADD START
	
	/** 基準日(端末補償申込年月日) */
	public static final String STD_DT_TMCP_MSKM_YMD = "7";
	
// △△△ ANK-3484-00-00 ADD END
// ▽▽▽ ANK-3754-00-00 ADD START
	
	/** 基準日(工事完了日) */
	public static final String STD_DT_KOJIAK_JSSI_YMD = "8";	
// △△△ ANK-3754-00-00 ADD END
	
	/** 基準日からの相対日(+0) */
	public static final String RELATIVE_DATE_COUNT_0 = "0";

	/** 基準日からの相対日(翌月月初) */
	public static final String RELATIVE_DATE_COUNT_NEXT = "2";

	/** 基準日からの相対日(翌々月月初) */
	public static final String RELATIVE_DATE_COUNT_NEXT_NX = "3";

	/** 月初設定用 */
	public static final String GESYO_SETTEI = "01";

	/** 月途中日付 */
	public static final String HALF_DATE = "16";

	/** 優先基準日(オプションサービスのサービス開始希望日との大きい方) */
	public static final String PRIORITY_STD_DT_STA_KIBO = "1";

	/** 優先基準日(オプションサービスのサービス開始希望日、運用日の最大の物) */
	public static final String PRIORITY_STD_DT_MAX = "2";

	/** 優先基準日(運用日付との大きい方) */
	public static final String PRIORITY_STD_DT_OPE_DATE = "3";

	/** 優先基準日(サービス契約のサービス課金開始年月日が、請求年月の末日より大きい場合は、
		サービス課金開始年月日の前日と運用日の小さい方) */
	public static final String PRIORITY_STD_DT_SRV_KAKIN_YMD_END_DAY_4 = "4";

	/** 優先基準日(関連機器出荷完了日+10日) */
	public static final String PRIORITY_STD_DT_KANREN_KIKI_SYUKKA_DAY = "5";

	/** 優先基準日(サービス契約のサービス課金開始年月日が、請求年月の末日より大きい場合は、
		サービス課金開始年月日の同月末日と運用日の小さい方) */
	public static final String PRIORITY_STD_DT_SRV_KAKIN_YMD_END_DAY_6 = "6";

// ▽▽▽ ANK-3484-00-00 ADD START

	/** 優先基準日(親のサービス契約のサービス課金開始日との大きい方) */
	public static final String PRIORITY_STD_DT_OYA_SVC_KEI_CHRG_STA_YMD = "7";
	
// △△△ ANK-3484-00-00 ADD END

// ▽▽▽ ANK-3754-00-00 ADD START
	/** 優先基準日(オプションサービスのサービス開始希望日と関連機器出荷完了日+10日との大きい方) */
	public static final String PRIORITY_STD_DT_STA_KIBO_KANREN_KIKI_SYUKKA_DAY = "8";
	
// △△△ ANK-3754-00-00 ADD END

	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** サービスコード */
	private String svc_cd = null;

	/** オプションサービスコード */
	private String op_svc_cd = null;

	/** 異動区分 */
	private String ido_kbn = null;
	
	/** 申込期間 */
	private String mskm_period = null;

	/** 即時／翌月 */
	private String skj_ykjt = null;

	/** 元のサービス契約のサービス開始日 */
	private String kk0081_svc_sta_ymd = null;

// ▽▽▽ ANK-3754-00-00 ADD START
	/** 工事会社配送フラグ */
	private String kochai_flg = null;
// △△△ ANK-3754-00-00 ADD END

	/** サービス開始年月日(入力) */
	private String input_svc_sta_ymd = null;

	/** 申込受付年月日 */
	private String kk0011_mskm_uk_ymd = null;

	/** サービス利用開始希望年月日 */
	private String svc_use_sta_kibo_ymd = null;

	/** 料金計算日より求めた請求年月の末日(「スマートリンクプレミアム」オプション専用) */
	private String ch0501_seiky_ymd = null;

	/** 関連機器出荷完了日+10日（「スマートリンクプレミアム」オプション専用） */
	private String dk0011_Haiso_Fin_Ymd_Add10 = null;

	/** 元のサービス契約の料金グループ */
	private String kk0081_prc_grp_cd = null;
	
// ▽▽▽ ANK-3484-00-00 ADD START

	/** 親のサービス契約課金開始日 */
	private String kk0081_svc_chrg_sta_ymd = null;
	
	/** 端末補償申込年月日 */
	private String tmcp_mskm_ymd = null;

// △△△ ANK-3484-00-00 ADD ENDT
// ▽▽▽ ANK-3754-00-00 ADD START
	/** 工事完了日 */
	private String kojiak_jssi_ymd = null;
// △△△ ANK-3754-00-00 ADD END

	/**
	 * <p>
	 * JKKejbRule0074001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0074001(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 getOp_svc_cd()
	{
		return this.op_svc_cd;
	}

	/**
	 * <p>
	 * 異動区分を取得します。
	 * </p>
	 * @return 異動区分
	 */
	public String getIdo_kbn()
	{
		return this.ido_kbn;
	}

	/**
	 * <p>
	 * 申込期間を取得します。
	 * </p>
	 * @return 申込期間
	 */
	private String getMskm_period()
	{
		return this.mskm_period;
	}

	/**
	 * <p>
	 * 即時／翌月を取得します。
	 * </p>
	 * @return 即時／翌月
	 */
	private String getSkj_ykjt()
	{
		return this.skj_ykjt;
	}

	/**
	 * <p>
	 * 元のサービス契約のサービス開始日を取得します。
	 * </p>
	 * @return 元のサービス契約のサービス開始日
	 */
	private String getKk0081_svc_sta_ymd()
	{
		return this.kk0081_svc_sta_ymd;
	}

	// ▽▽▽ ANK-3754-00-00 ADD START
	/**
	 * <p>
	 * 工事会社配送フラグを取得します。
	 * </p>
	 * @return 工事会社配送フラグ
	 */
	private String getKochai_flg()
	{
		return this.kochai_flg;
	}
	// △△△ ANK-3754-00-00 ADD END

	/**
	 * <p>
	 * サービス開始年月日(入力)を取得します。
	 * </p>
	 * @return サービス開始年月日(入力)
	 */
	private String getInput_svc_sta_ymd()
	{
		return this.input_svc_sta_ymd;
	}

	/**
	 * <p>
	 * 申込受付年月日を取得します。
	 * </p>
	 * @return 申込受付年月日
	 */
	private String getKk0011_mskm_uk_ymd()
	{
		return this.kk0011_mskm_uk_ymd;
	}

	/**
	 * <p>
	 * サービス利用開始希望年月日を取得します。
	 * </p>
	 * @return サービス利用開始希望年月日
	 */
	private String getSvc_use_sta_kibo_ymd()
	{
		return this.svc_use_sta_kibo_ymd;
	}

	/**
	 * <p>
	 * 料金計算日より求めた請求年月の末日を取得します。
	 * </p>
	 * @return 料金計算日より求めた請求年月の末日
	 */
	public String getCh0501_seiky_ymd()
	{
		return this.ch0501_seiky_ymd;
	}

	/**
	 * <p>
	 * 関連機器出荷完了日+10日を取得します。
	 * </p>
	 * @return 関連機器出荷完了日+10日
	 */
	public String getDk0011_Haiso_Fin_Ymd_Add10()
	{
		return this.dk0011_Haiso_Fin_Ymd_Add10;
	}

	/**
	 * <p>
	 * 元のサービス契約の料金グループコードを取得します。
	 * </p>
	 * @return 元のサービス契約の料金グループコード
	 */
	public String getKk0081_prc_grp_cd()
	{
		return this.kk0081_prc_grp_cd;
	}

	/**
	 * <p>
	 * サービスコードを設定します。
	 * </p>
	 * @param p_svc_cd サービスコード
	 */
	public void setSvc_cd(String p_svc_cd)
	{
		this.svc_cd = p_svc_cd;
	}

	/**
	 * <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_ido_kbn 異動区分
	 */
	public void setIdo_kbn(String p_ido_kbn)
	{
		this.ido_kbn = p_ido_kbn;
	}

	/**
	 * <p>
	 * 申込期間を設定します。
	 * </p>
	 * @param p_mskm_period 申込期間
	 */
	public void setMskm_period(String p_mskm_period)
	{
		this.mskm_period = p_mskm_period;
	}

	/**
	 * <p>
	 * 即時／翌月を設定します。
	 * </p>
	 * @param p_skj_ykjt 即時／翌月
	 */
	public void setSkj_ykjt(String p_skj_ykjt)
	{
		this.skj_ykjt = p_skj_ykjt;
	}

	/**
	 * <p>
	 * 元のサービス契約のサービス開始日を設定します。
	 * </p>
	 * @param p_kk0081_svc_sta_ymd 元のサービス契約のサービス開始日
	 */
	public void setKk0081_svc_sta_ymd(String p_kk0081_svc_sta_ymd)
	{
		this.kk0081_svc_sta_ymd = p_kk0081_svc_sta_ymd;
	}

	// ▽▽▽ ANK-3754-00-00 ADD START
	/**
	 * <p>
	 * 工事会社配送フラグを設定します。
	 * </p>
	 * @param p_haiso_flg 工事会社配送
	 */
	public void setKochai_flg(String p_kochai_flg)
	{
		this.kochai_flg = p_kochai_flg;
	}
	// △△△ ANK-3754-00-00 ADD END

	/**
	 * <p>
	 * サービス開始年月日(入力)を設定します。
	 * </p>
	 * @param p_input_svc_sta_ymd サービス開始年月日(入力)
	 */
	public void setInput_svc_sta_ymd(String p_input_svc_sta_ymd)
	{
		this.input_svc_sta_ymd = p_input_svc_sta_ymd;
	}

	/**
	 * <p>
	 * 申込受付年月日を設定します。
	 * </p>
	 * @param p_kk0011_mskm_uk_ymd 申込受付年月日
	 */
	public void setKk0011_mskm_uk_ymd(String p_kk0011_mskm_uk_ymd)
	{
		this.kk0011_mskm_uk_ymd = p_kk0011_mskm_uk_ymd;
	}

	/**
	 * <p>
	 * サービス利用開始希望年月日を設定します。
	 * </p>
	 * @param p_svc_use_sta_kibo_ymd サービス利用開始希望年月日
	 */
	public void setSvc_use_sta_kibo_ymd(String p_svc_use_sta_kibo_ymd)
	{
		this.svc_use_sta_kibo_ymd = p_svc_use_sta_kibo_ymd;
	}
	
	/**
	 * <p>
	 * 料金計算日より求めた請求年月の末日を設定します。
	 * </p>
	 * @param p_ch0501_seiky_ymd 料金計算日より求めた請求年月の末日
	 */
	public void setCh0501_seiky_ymd(String p_ch0501_seiky_ymd)
	{
		this.ch0501_seiky_ymd = p_ch0501_seiky_ymd;
	}

	/**
	 * <p>
	 * 関連機器出荷完了日+10日を設定します。
	 * </p>
	 * @param p_dk0011_Haiso_Fin_Ymd_Add10 関連機器出荷完了日+10日
	 */
	public void setDk0011_Haiso_Fin_Ymd_Add10(String p_dk0011_Haiso_Fin_Ymd_Add10)
	{
		this.dk0011_Haiso_Fin_Ymd_Add10 = p_dk0011_Haiso_Fin_Ymd_Add10;
	}

	/**
	 * <p>
	 * 元のサービス契約の料金グループコードを設定します。
	 * </p>
	 * @param p_kk0081_prc_grp_cd 元のサービス契約の料金グループコード
	 */
	public void setKk0081_prc_grp_cd(String p_kk0081_prc_grp_cd)
	{
		this.kk0081_prc_grp_cd = p_kk0081_prc_grp_cd;
	}

	/**
	 * <p>
	 * 相関ルールの結果により取得した開始年月日を算出します。
	 * </p>
	 * @return 算出した開始年月日を返却
	 */
	public String getStaYmd()
	{
		// ログ出力
		execLogOutput();

		String ymd = null;
		String stdardDay = null;

		// ルールエンジンで使用する値を設定
		set(SVC_CD, getSvc_cd());
		set(OP_SVC_CD, getOp_svc_cd());
		set(IDO_KBN, getIdo_kbn());
		set(MSKM_PRD, getMskm_period());
		set(SKJ_YKJT, getSkj_ykjt());
		set(KK0081_SVC_STA_YMD, convSvcStaYmd(getKk0081_svc_sta_ymd()));
		set(PRC_GRP_CD, getKk0081_prc_grp_cd());
		// ▽▽▽ ANK-3754-00-00 ADD START
		set(KOCHAI_FLG, getKochai_flg());
		// △△△ ANK-3754-00-00 ADD END

		// ルールエンジンの実行
		super.execRuleEngine();

		// 実行結果が存在しない場合、nullを返す。
		if (!hasNext())
		{
			return ymd;
		}

		// ルールエンジンの実行結果を取得する
		HashMap<String, Object> retMap = getResultMap();

		// 実行結果の基準日が「サービス契約のサービス開始年月日」の場合
		if (STD_DT_KK0081_SVC_STA.equals(retMap.get(STD_DT)))
		{
			// 「元のサービス契約のサービス開始日」を基準日とする
			stdardDay = getKk0081_svc_sta_ymd();
		}

		// 実行結果の基準日が「申込受付日」の場合
		else if (STD_DT_KK0011_MSKM_UK.equals(retMap.get(STD_DT)))
		{
			// 「申込受付年月日」を基準日とする
			stdardDay = getKk0011_mskm_uk_ymd();
		}

		// 実行結果の基準日が「NHK指定の開始日」の場合
		else if (STD_DT_NHK_STA.equals(retMap.get(STD_DT)))
		{
			// 「サービス利用開始希望年月日」を基準日とする
			stdardDay = getSvc_use_sta_kibo_ymd();
		}

		// 実行結果の基準日が「入力値のサービス開始年月日」の場合
		else if (STD_DT_INPUT.equals(retMap.get(STD_DT)))
		{
			// 「サービス開始年月日(入力)」を基準日とする
			stdardDay = getInput_svc_sta_ymd();
		}
		// 実行結果の基準日が「料金計算日より求めた請求年月の末日」の場合
		else if (STD_DT_CH0501_SEIKY_YMD.equals(retMap.get(STD_DT)))
		{
			stdardDay = getCh0501_seiky_ymd();
		}
// ▽▽▽ ANK-3484-00-00 ADD START
		// 実行結果の基準日が「端末補償申込年月日」の場合
		else if (STD_DT_TMCP_MSKM_YMD.equals(retMap.get(STD_DT)))
		{
			stdardDay = getTmcp_mskm_ymd();
		}
// △△△ ANK-3484-00-00 ADD END
// ▽▽▽ ANK-3754-00-00 ADD START
		// 実行結果の基準日が「工事完了日」の場合
		else if (STD_DT_KOJIAK_JSSI_YMD.equals(retMap.get(STD_DT)))
		{
			stdardDay = getKojiak_jssi_ymd();
		}
// △△△ ANK-3754-00-00 ADD END

		// 開始年月日の算出処理を行う
		ymd = getYmd(retMap, stdardDay);

		return ymd;
	}

	/**
	 * <p>
	 * 開始年月日を算出します。
	 * </p>
	 * @param retMap ルールの結果
	 * @param stdardDay 基準日
	 * @return 算出した開始年月日
	 */
	private String getYmd(HashMap<String, Object> retMap, String stdardDay)
	{
		String staYmd = null;

		// 基準日が未設定の場合は、処理を終了する
		if (null == stdardDay || "".equals(stdardDay))
		{
			return staYmd;
		}

		// 基準日からの相対日が"+0"の場合
		if (RELATIVE_DATE_COUNT_0.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日を「開始日」とする
			staYmd = stdardDay;
		}

		// 基準日からの相対日が"翌月月初"の場合
		else if (RELATIVE_DATE_COUNT_NEXT.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日の翌月を算出する
			try
			{
				staYmd = JKKModelCommon.addMonth(stdardDay, 1);
			}
			catch (ParseException ce)
			{
				throw new CAANRuntimeException(ce);
			}

			// 年月を抽出し、1日に設定する
			String ym = staYmd.substring(0, 6);

			// 基準日の翌月1日を「課金開始日」とする
			staYmd = ym + GESYO_SETTEI;
		}

		// 基準日からの相対日が"翌々月月初"の場合
		else if (RELATIVE_DATE_COUNT_NEXT_NX.equals(retMap.get(RELATIVE_DATE_COUNT)))
		{
			// 基準日の翌々月を算出する
			try
			{
				staYmd = JKKModelCommon.addMonth(stdardDay, 2);
			}
			catch (ParseException ce)
			{
				throw new CAANRuntimeException(ce);
			}

			// 年月を抽出し、1日に設定する
			String ym = staYmd.substring(0, 6);

			// 基準日の翌月1日を「課金開始日」とする
			staYmd = ym + GESYO_SETTEI;
		}

		// 開始年月日を決定する
		return setStaYmd(retMap, staYmd);
	}

	/**
	 * <p>
	 * 開始年月日を決定します。
	 * </p>
	 * @param retMap ルールの結果
	 * @param staYmd 暫定の開始年月日
	 * @return 決定した開始年月日
	 */
	private String setStaYmd(HashMap<String, Object> retMap, String staYmd)
	{
		String svcUseStaKiboYmd = getSvc_use_sta_kibo_ymd();
		String opeDate = JKKModelCommon.getOpeDate(new CAANMsg());

		// 優先基準日が"オプションサービスのサービス開始希望日との大きい方"の場合
		if (PRIORITY_STD_DT_STA_KIBO.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// サービス利用開始希望年月日が未設定の場合は、処理を終了する
			if (null == svcUseStaKiboYmd || "".equals(svcUseStaKiboYmd))
			{
				return staYmd;
			}

			// 開始日をメンバ変数のサービス利用開始希望年月日と比較し、
			// 日付が大きい方を「開始日」とする
			if (staYmd.compareTo(svcUseStaKiboYmd) < 0)
			{
				return svcUseStaKiboYmd;
			}
		}

		// 優先基準日が"優先基準日(オプションサービスのサービス開始希望日、運用日の最大の物)"の場合
		else if (PRIORITY_STD_DT_MAX.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// 開始日、運用日付をメンバ変数のサービス利用開始希望年月日と比較し、
			// 最も大きい日付を「開始日」とする
			ArrayList<String> arrayMax = new ArrayList<String>();

			arrayMax.add(staYmd);
			arrayMax.add(opeDate);

			// サービス利用開始希望年月日が未設定の場合は、リストに含めない
			if (null != svcUseStaKiboYmd && !"".equals(svcUseStaKiboYmd))
			{
				arrayMax.add(svcUseStaKiboYmd);
			}

			// 処理対象のリストをソートし、昇順になったソート順を降順に逆転させる
			Collections.sort(arrayMax);
			Collections.reverse(arrayMax);

			// 最大の物が「開始日」となる
			return arrayMax.get(0);
		}

		// 優先基準日が"運用日付との大きい方"の場合
		else if (PRIORITY_STD_DT_OPE_DATE.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// 開始日を運用日付と比較し、
			// 日付が大きい方を「開始日」とする
			if (staYmd.compareTo(opeDate) < 0)
			{
				return opeDate;
			}
		}
		// 優先基準日が"サービス契約のサービス課金開始年月日が、請求年月の末日より大きい場合は、
		// サービス課金開始年月日の前日と運用日の小さい方"またはサービス課金開始年月日の同月末日と運用日の小さい方"の場合
		else if (PRIORITY_STD_DT_SRV_KAKIN_YMD_END_DAY_4.equals(retMap.get(PRIORITY_STD_DT)) 
				|| PRIORITY_STD_DT_SRV_KAKIN_YMD_END_DAY_6.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// オプションサービス契約番号が入力されている場合
			if (!getCBSMsg().isNull(EKK0361C040CBSMsg.OP_SVC_KEI_NO))
			{
				// 優先基準日を取得します
				String svcKakinStaYmd = this.getSrvKakinKaishiYmd(getCBSMsg().getString(EKK0361C040CBSMsg.OP_SVC_KEI_NO), staYmd, retMap.get(PRIORITY_STD_DT));

				// 優先基準日がnullの場合
				if (svcKakinStaYmd == null)
				{
					return staYmd;
				}
				return svcKakinStaYmd;
			}
		}
		// 優先基準日が"関連機器出荷完了日+10日"の場合
		else if (PRIORITY_STD_DT_KANREN_KIKI_SYUKKA_DAY.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// 「基準日」＜「関連機器出荷完了日+10日」の場合
			if (getDk0011_Haiso_Fin_Ymd_Add10() != null && 
					JKKModelCommon.isFutureDate(getDk0011_Haiso_Fin_Ymd_Add10(), staYmd, "0"))
			{
				// 「関連機器出荷完了日+10日」を返却する
				return getDk0011_Haiso_Fin_Ymd_Add10();
			}
		}
// ▽▽▽ ANK-3484-00-00 ADD START
		// 実行結果の基準日が「親のサービス契約のサービス課金開始日との大きい方」の場合
		else if (PRIORITY_STD_DT_OYA_SVC_KEI_CHRG_STA_YMD.equals(retMap.get(PRIORITY_STD_DT)))
		{
			if (staYmd.compareTo(getKk0081_svc_chrg_sta_ymd()) < 0)
			{
				return getKk0081_svc_chrg_sta_ymd();
			}
		}
// △△△ ANK-3484-00-00 ADD END
// ▽▽▽ ANK-3754-00-00 ADD START
		// 実行結果の基準日がオプションサービスのサービス開始希望日と関連機器出荷完了日+10日との大きい方
		else if (PRIORITY_STD_DT_STA_KIBO_KANREN_KIKI_SYUKKA_DAY.equals(retMap.get(PRIORITY_STD_DT)))
		{
			// 開始日、運用日付をメンバ変数のサービス利用開始希望年月日と比較し、
			// 最も大きい日付を「開始日」とする
			ArrayList<String> arrayMax = new ArrayList<String>();
			String haisoYmdAdd10 = getDk0011_Haiso_Fin_Ymd_Add10();

			arrayMax.add(staYmd);

			// サービス利用開始希望年月日が未設定の場合は、リストに含めない
			if (null != svcUseStaKiboYmd && !"".equals(svcUseStaKiboYmd))
			{
				arrayMax.add(svcUseStaKiboYmd);
			}
			// 関連機器出荷完了日+10日が未設定の場合は、リストに含めない
			if (null != haisoYmdAdd10 && !"".equals(haisoYmdAdd10))
			{
				arrayMax.add(haisoYmdAdd10);
			}

			// 処理対象のリストをソートし、昇順になったソート順を降順に逆転させる
			Collections.sort(arrayMax);
			Collections.reverse(arrayMax);

			// 最大の物が「開始日」となる
			return arrayMax.get(0);

		}
// △△△ ANK-3754-00-00 ADD END

		return staYmd;
	}

	/**
	 * <p>
	 * サービス開始年月日期間変換処理を行います。
	 * </p>
	 * @param svcStaYmd 元のサービス契約のサービス開始日（日付）
	 * @return 元のサービス契約のサービス開始日（値）
	 */
	private String convSvcStaYmd(String svcStaYmd)
	{
		// 元のサービス契約のサービス開始日が未設定の場合はnullを返却する
		if (svcStaYmd == null || "".equals(svcStaYmd))

		{
			return null;
		}
		
		// サービス開始年月日から日付を取得
		String dd = JKKModelCommon.toDayFromYmd(svcStaYmd);

		// パラメータの日付部分が15日以下の場合、「1〜15日」を返却する
		if (HALF_DATE.compareTo(dd) > 0)
		{
			return KK0081_SVC_STA_FIRST;
		}

		// それ以外の場合、「16〜末日」を返却する
		return KK0081_SVC_STA_SECOND;
	}

	/**
	 * <p>
	 * オプションサービス契約のサービス契約番号に紐づくサービス契約のサービス課金開始年月日
	 * を取得し、請求年月を編集して返却します
	 * </p>
	 * @param opt_srv_kei_no オプションサービス契約番号
	 * @param starYmd 基準日
	 * @param prityStdDt ルール判定結果の優先基準日
	 * @return 優先基準日
	 */
	private String getSrvKakinKaishiYmd(String opt_srv_kei_no, String starYmd, Object prityStdDt)
	{
		// オプションサービス契約＜ISP＞をカレント検索する
		CAANMsg kk0351msg = this.getCurrentKK0351(opt_srv_kei_no);

		// 検索結果が0件の場合
		if (kk0351msg == null)
		{
			return null;
		}

		// サービス契約番号が未設定の場合
		if (kk0351msg.isNull(KK0351ETMsg.SVC_KEI_NO))
		{
			return null;
		}

		// オプションサービス契約のサービス契約番号に紐づくサービス契約のカレントレコードを取得
		CAANMsg kk0081msg = this.getCurrentKK0081(kk0351msg.getString(KK0351ETMsg.SVC_KEI_NO));

		// 検索結果が0件の場合
		if (kk0081msg == null)
		{
			return null;
		}

		// サービス課金開始年月日が未設定の場合
		if (kk0081msg.isNull(KK0081ETMsg.SVC_CHRG_STAYMD))
		{
			return null;
		}

		String svcChrgStaYmd = kk0081msg.getString(KK0081ETMsg.SVC_CHRG_STAYMD);

		// サービス契約のサービス課金開始年月日が請求年月の末日より大きい場合
		if (svcChrgStaYmd.compareTo(starYmd) > 0)
		{
			// 運用日を取得する
			String opeDate = JKKModelCommon.getOpeDate(inCBSMsg);
			
			// ルール判定結果の優先基準日が「サービス課金開始年月日の前日と運用日の小さい方」の場合
			if (PRIORITY_STD_DT_SRV_KAKIN_YMD_END_DAY_4.equals(prityStdDt))
			{
				// サービス課金開始日の前日を取得
				String svcChrgBeforeYmd = JPCDateUtil.addDay(svcChrgStaYmd, -1);
				
				// サービス課金開始年月日の前日＜運用日の場合
				if (svcChrgBeforeYmd.compareTo(opeDate) < 0)
				{
					// サービス課金開始日の前日を返却
					return svcChrgBeforeYmd;
				}
				// サービス課金開始年月日の前日＞＝運用日の場合
				else
				{
					// 運用日を返却
					return opeDate;
				}
			}
			// ルール判定結果の優先基準日が「サービス課金開始年月日の同月末日と運用日の小さい方」の場合
			else
			{
				// サービス課金開始日同月末日を取得
				String day = JPCDateUtil.getEndOfMonth(svcChrgStaYmd.substring(0, 6));
				String svcChrgEndYmd = svcChrgStaYmd.substring(0, 6).concat(day);
				
				// サービス課金開始年月日と同月末日＜運用日の場合
				if (svcChrgEndYmd.compareTo(opeDate) < 0)
				{
					// サービス課金開始日同月末日を返却
					return svcChrgEndYmd;
				}
				// サービス課金開始年月日と同月末日＞＝運用日の場合
				else
				{
					// 運用日を返却
					return opeDate;
				}
			}
		}
		return starYmd;
	}

	/**
	 * <p>
	 * サービス契約のカレントレコードを取得します
	 * </p>
	 * @param srv_kei_no サービス契約番号
	 * @return サービス契約のカレントレコード
	 */
	private CAANMsg getCurrentKK0081(String srv_kei_no)
	{
		// サービス契約のカレント検索を行う
		CAANMsg msg = new CAANMsg(KK0081ETMsg.class.getName());
		msg.set(KK0081ETMsg.SVC_KEI_NO, srv_kei_no);
		msg.set(KK0081ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		return new JKKejbKK0081DBABase().findByCurrent(msg);
	}
	
	/**
	 * <p>
	 * オプションサービス契約＜ISP＞のカレントレコードを取得します
	 * </p>
	 * @param opt_srv_kei_no オプションサービス契約番号
	 * @return オプションサービス契約＜ISP＞のカレントレコード
	 */
	private CAANMsg getCurrentKK0351(String opt_srv_kei_no)
	{
		// オプションサービス契約＜ISP＞のカレント検索を行う
		CAANMsg msg = new CAANMsg(KK0351ETMsg.class.getName());
		msg.set(KK0351ETMsg.OP_SVC_KEI_NO, opt_srv_kei_no);
		msg.set(KK0351ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		return new JKKejbKK0351DBABase().findByCurrent(msg);
	}
	
	/**
	 * <p>
	 * メンバ変数のログ出力を行う。
	 * </p>
	 */
	private void execLogOutput()
	{
		// サービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.svc_cd=" + getSvc_cd());

		// オプションサービスコード
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.op_svc_cd=" + getOp_svc_cd());

		// 申込期間
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.mskm_period=" + getMskm_period());

		// 即時／翌月
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.skj_ykjt=" + getSkj_ykjt());

		// 元のサービス契約のサービス開始日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.kk0081_svc_sta_ymd=" + getKk0081_svc_sta_ymd());

		// サービス開始年月日(入力)
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.input_svc_sta_ymd=" + getInput_svc_sta_ymd());

		// 申込受付年月日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.kk0011_mskm_uk_ymd=" + getKk0011_mskm_uk_ymd());

		// サービス利用開始希望年月日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.svc_use_sta_kibo_ymd=" + getSvc_use_sta_kibo_ymd());

		// 料金計算日より求めた請求年月の末日
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.ch0501_seiky_ymd=" + getCh0501_seiky_ymd());
		
		// 元のサービス契約の料金グループ
		JSYejbLog.println(JSYejbLog.DEBUG, getClass(), "JKKejbRule0074001.kk0081_prc_grp_cd=" + getKk0081_prc_grp_cd());
	}
// ▽▽▽ ANK-3484-00-00 ADD START

	/**
	 * 親のサービス課金開始日を返す
	 * <p>
	 * @return サービス契約のサービス課金開始日
	 */
	private String getKk0081_svc_chrg_sta_ymd()
	{
		return kk0081_svc_chrg_sta_ymd;
	}
	/**
	 * 親のサービス課金開始日を設定する
	 * <p>
	 * @param kk0081_svc_chrg_sta_ymd
	 */
	public void setKk0081_svc_chrg_sta_ymd(String kk0081_svc_chrg_sta_ymd)
	{
		this.kk0081_svc_chrg_sta_ymd = kk0081_svc_chrg_sta_ymd;
	}
	/**
	 * 端末補償申込年月日を返す。
	 * <p>
	 * @return 端末補償申込年月日
	 */
	private String getTmcp_mskm_ymd() 
	{
		return tmcp_mskm_ymd;
	}
	/**
	 * 端末補償年月日を設定する。
	 * <p>
	 * @param tmcp_mskm_ymd 端末補償申込年月日
	 */
	public void setTmcp_mskm_ymd(String tmcp_mskm_ymd)
	{
		this.tmcp_mskm_ymd = tmcp_mskm_ymd;
	}
// △△△ ANK-3484-00-00 ADD END
// ▽▽▽ ANK-3754-00-00 ADD START
	/**
	 * 工事完了日を返す。
	 * <p>
	 * @return 工事完了日
	 */
	private String getKojiak_jssi_ymd() 
	{
		return kojiak_jssi_ymd;
	}
	/**
	 * 工事完了日を設定する。
	 * <p>
	 * @param kojiak_jssi_ymd 工事完了日
	 */
	public void setKojiak_jssi_ymd(String kojiak_jssi_ymd)
	{
		this.kojiak_jssi_ymd = kojiak_jssi_ymd;
	}
// △△△ ANK-3754-00-00 ADD END
}
