/*********************************************************************
 *   All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *  システム名		：eo顧客基幹システム
 *  モジュール名	：JKKejbEKK0351C130Edit
 *  ソースファイル名：JKKejbEKK0351C130Edit.java
 *  作成者			：富士通
 *  日付			：2011年11月11日
 *＜機能概要＞
 *  オプションサービス契約料金プラン変更確定編集部品クラス
 *＜修正履歴＞
 *  バージョン  修正日		修正者		修正内容
 *  v1.00.00    2011/11/11  富士通      新規作成
 *  v4.00.00    2013/07/15  FJ)竹内     TG1-2013-0000704
 *  v39.00.00   2018/10/01  FJ)舘山		【ANK-3484-00-00】_端末補償サービス導入対応
 *
 **********************************************************************/

package eo.ejb.common.edit;

import java.util.List;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0011ETMsg;
import eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbm.entity.KK0361ETMsg;
import eo.ejb.cbm.entity.KK0351LE;
import eo.ejb.cbm.entity.KK1681ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0351C130CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0011DBABase;
import eo.ejb.common.db.JKKejbKK0021DBABase;
import eo.ejb.common.db.JKKejbKK0351DBABase;
import eo.ejb.common.db.JKKejbKK0361DBABase;
import eo.ejb.common.db.JKKejbKK0351ETDA;
import eo.ejb.common.entity.JKKejbIdoRsvAccess;
import eo.ejb.common.entity.JKKejbKRCKCommon;
import eo.ejb.common.rule.JKKejbRule0066001;
import eo.ejb.common.rule.JKKejbRule0074001;
import eo.ejb.common.rule.JKKejbRule0088001;

/**
 * <p>
 * オプションサービス契約の相関ルール処理を呼び出す為の編集を行う部品クラスです
 * </p>
 * @author 富士通
 */
public class JKKejbEKK0351C130Edit
{

	/** サービスコード（テレビサービス）*/
	private static final String SVC_CD_TV = "03";

	/** サービスコード（ホスティングサービス）*/
	private static final String SVC_CD_HOST = "04";

	/** 無効フラグ（有効）*/
	private static final String MK_FLG_YUKO = "0";

	/** 異動予約詳細コード オプション開始 */
	private static final String IDO_RSV_DTL_OPSTA = "014";

	/**
	 * コンストラクタです
	 */
	public JKKejbEKK0351C130Edit()
	{
	}

	/**
	 * <p>
	 * オプションサービス契約の開始年月日設定の相関ルールを呼び出し、
	 * 開始年月日を設定します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 開始年月日
	 */
	public Object getStaYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0351C130Edit#getStaYmd");

		// オプションサービス契約のカレント検索を行う
		CAANMsg kk0351Msg = getCurrentKK0351(inMsg);

		// 存在しない場合
		if (null == kk0351Msg)
		{
			return null;
		}

		// オプションサービス契約のプライマリ検索を行う
		CAANMsg kk0351MsgP = getPrimaryKK0351(inMsg);

		// 存在しない場合
		if (null == kk0351MsgP)
		{
			return null;
		}

		// 相関ルールを実行する
		String staYmd = this.staYmdRuleRun(inMsg, kk0351Msg, kk0351MsgP);

		// 開始年月日が取得できなかった場合、エラー処理を行う
		if (null == staYmd || "".equals(staYmd))
		{
			// 関連制約エラーのステータスを設定
			inMsg.set(EKK0351C130CBSMsg.OP_SVC_KEI_NO_ERR, "EB");
			inMsg.set(EKK0351C130CBSMsg.STATUS, StatusCodes.RELATION_ERR);

			return null;
		}

		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "end:JKKejbEKK0351C130Edit#getStaYmd");

		return staYmd;
	}

	/**
	 * <p>
	 * 開始年月日設定の相関ルールを呼び出し開始年月日を取得します
	 * 
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param kk0351Msg オプションサービス契約のカレント検索結果
	 * @param kk0351MsgP オプションサービス契約のプライマリ検索結果 
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 開始年月日
	 */
	private String staYmdRuleRun(CAANMsg inMsg, CAANMsg kk0351Msg, CAANMsg kk0351MsgP)
	{
		// 相関ルールを呼び出す為にインスタンス生成する
		JKKejbRule0074001 instance = new JKKejbRule0074001(inMsg);

		// 親契約識別コードを元に取得したサービス契約番号で
		// サービス契約をカレント検索する
		CAANMsg kk0081Msg = new JKKejbKRCKCommon().getOyaKK0081(inMsg, kk0351Msg);

		// プライマリ検索で取得したオプションサービス契約の
		// 申込明細番号をキーに申込明細をカレント検索する
		CAANMsg kk0021Msg = getCurrentKK0021(inMsg, kk0351MsgP.getString(KK0351ETMsg.MSKM_DTL_NO));

		// 取得した申込明細の申込番号をキーに申込をカレント検索する
		CAANMsg kk0011Msg = getCurrentKK0011(inMsg, kk0021Msg.getString(KK0021ETMsg.MSKM_NO));

		// サービスコードを設定する
		instance.setSvc_cd(kk0081Msg.getString(KK0081ETMsg.SVC_CD));

		// オプションサービスコードを設定する
		instance.setOp_svc_cd(kk0351Msg.getString(KK0351ETMsg.OP_SVC_CD));

		// 申込明細から申込日を取得する
		String mskmYmd = kk0021Msg.getString(KK0021ETMsg.MSKM_YMD);

		// 申込期間を取得する
		String mskmPeriod = this.getMskmPeriod(inMsg, mskmYmd, kk0081Msg.getString(KK0081ETMsg.SVC_STA_YMD), kk0081Msg
				.getString(KK0081ETMsg.SVC_CHRG_STAYMD));
		// 申込期間が未設定または期間未定の場合はnullを返却（関連制約エラーとする）
		if (mskmPeriod == null || "0".equals(mskmPeriod))
		{
			return null;
		}
		// 申込期間を設定する
		instance.setMskm_period(mskmPeriod);

		// 即時／翌月を設定する
		instance.setSkj_ykjt(inMsg.getString(EKK0351C130CBSMsg.SKJ_YKJT));

		// サービス開始年月日(サービス契約)を設定する
		instance.setKk0081_svc_sta_ymd(kk0081Msg.getString(KK0081ETMsg.SVC_STA_YMD));

		// 申込受付年月日を設定する
		instance.setKk0011_mskm_uk_ymd(getMskmYmd(kk0011Msg.getString(KK0011ETMsg.MSKM_UK_DTM)));

		// サービス利用開始希望年月日を設定する
		instance.setSvc_use_sta_kibo_ymd(kk0351MsgP.getString(KK0351ETMsg.SVC_USE_STA_KIBO_YMD));

// ▽▽▽ ANK-3484-00-00 ADD START
		// サービス課金開始日（サービス契約）を設定する。
		instance.setKk0081_svc_chrg_sta_ymd(kk0081Msg.getString(KK0081ETMsg.SVC_CHRG_STAYMD));
		CAANMsg kk0361Msg = getCurrentKK0361(kk0351Msg);
		if (kk0361Msg != null)
		{
			instance.setTmcp_mskm_ymd(kk0361Msg.getString(KK0361ETMsg.TMCP_MSKM_YMD));
		}
// △△△ ANK-3484-00-00 ADD END
		
		// 相関ルールを実行して結果を返却する
		return instance.getStaYmd();

	}

	/**
	 * <p>
	 * 申込の申込受付年月日時分秒を年月日に編集します。
	 * </p>
	 * @param mskmUkDtm 申込の申込受付年月日時分秒
	 * @return CAANMsg 申込受付年月日時分秒を編集した年月日
	 */
	private String getMskmYmd(String mskmUkDtm)
	{
		// 年月日に編集する
		return JKKModelCommon.toYmdFromDtm(mskmUkDtm);
	}

	/**
	 * <p>
	 * オプションサービス契約の課金開始年月日設定の相関ルールを呼び出し、
	 * 課金開始年月日を設定します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 課金開始年月日
	 */
	public Object getChrgStaYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0351C130Edit#getChrgStaYmd");

		// オプションサービス契約のカレント検索を行う
		CAANMsg kk0351Msg = getCurrentKK0351(inMsg);

		// 存在しない場合
		if (null == kk0351Msg)
		{
			return null;
		}

		// 相関ルールを実行する
		String chagStaYmd = chrgStaYmdRuleRun(kk0351Msg, inMsg, inContext);

		// 課金開始年月日が取得できなかった場合、エラー処理を行う
		if (null == chagStaYmd || "".equals(chagStaYmd))
		{
			// 関連制約エラーのステータスを設定
			inMsg.set(EKK0351C130CBSMsg.OP_SVC_KEI_NO_ERR, "EB");
			inMsg.set(EKK0351C130CBSMsg.STATUS, StatusCodes.RELATION_ERR);

			return null;
		}

		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "end:JKKejbEKK0351C130Edit#getChrgStaYmd");

		return chagStaYmd;
	}

	/**
	 * <p>
	 * オプションサービス契約の課金開始年月日設定の相関ルールを呼び出し、
	 * 課金開始年月日を設定します(更新契機：解約時用)
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 課金開始年月日
	 */
	public Object getChrgStaYmdCancel(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0351C130Edit#getChrgStaYmdCancel");

		// オプションサービス契約のカレント検索を行う
		CAANMsg kk0351Msg = getCurrentKK0351(inMsg);

		// 存在しない場合
		if (null == kk0351Msg)
		{
			return null;
		}
		
		// 親契約識別コードを元に取得したサービス契約番号でサービス契約をカレント検索する
		CAANMsg kk0081Msg = new JKKejbKRCKCommon().getOyaKK0081(inMsg, kk0351Msg);
		// 親サービス契約のサービスコードを元に更新契機を決定します
		String svcCd = kk0081Msg.getString(KK0081ETMsg.SVC_CD);
		
		// 課金開始年月日
		String chagStaYmd = null;
		// 算出区分を「カレント」とする
		boolean updKbn = false;
		
		// 親サービス契約のサービスコードが"テレビサービス"または"ホスティングサービス"の場合
		if (SVC_CD_TV.equals(svcCd) || SVC_CD_HOST.equals(svcCd))
		{
			// 更新契機：解約時は"テレビサービス"または"ホスティングサービス"ではありえないのでカレント返却
			chagStaYmd = kk0351Msg.getString(KK0351ETMsg.PLAN_CHRG_STAYMD);
		}
		else
		{
			// 相関ルールを実行する
			chagStaYmd = new JKKejbKK0351ETDA().chrgStaYmdRuleRunForDsl(inMsg, kk0351Msg, kk0081Msg);
			// 算出区分を「ルール実施」とする
			updKbn = true;
		}

		// 相関ルールで課金開始年月日が取得できなかった場合、カレントのプラン課金開始年月日を返却する
		if (updKbn && (chagStaYmd == null || "".equals(chagStaYmd)))
		{
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "chrgStaYmd is Null !!");
			// 関連制約エラーのステータスを設定
			inMsg.set(EKK0351C130CBSMsg.OP_SVC_KEI_NO_ERR, "EB");
			inMsg.set(EKK0351C130CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return null;
		}
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "end:JKKejbEKK0351C130Edit#getChrgStaYmdCancel");

		return chagStaYmd;
	}

	/**
	 * <p>
	 * 課金開始日設定の相関ルールを呼び出し課金開始年月日を取得します
	 * </p>
	 * @param kk0351Msg オプションサービス契約のカレント検索結果
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 相関ルールより取得した課金開始年月日
	 */
	private String chrgStaYmdRuleRun(CAANMsg kk0351Msg, CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 相関ルールを呼び出す為にインスタンス生成する
		JKKejbRule0066001 instance = new JKKejbRule0066001(inMsg);

		// サービス開始年月日を取得する
		String svcStaYmd = (String)getStaYmd(inMsg, inContext);

		// 開始年月日が取得できなかった場合
		if (null == svcStaYmd || "".equals(svcStaYmd))
		{
			return null;
		}

		// 親契約識別コードを元に取得したサービス契約番号で
		// サービス契約をカレント検索する
		CAANMsg kk0081Msg = new JKKejbKRCKCommon().getOyaKK0081(inMsg, kk0351Msg);

		// サービス契約のサービス開始日を取得する
		String rule0088SvcStaYmd = kk0081Msg.getString(KK0081ETMsg.SVC_STA_YMD);

		// オプションサービス契約に紐付くサービス契約のサービス課金開始年月日を取得
		String svcChrgStaymd = kk0081Msg.getString(KK0081ETMsg.SVC_CHRG_STAYMD);
		
		// サービス契約のサービス開始年月日が未設定の場合
		if (rule0088SvcStaYmd == null)
		{
			// 異動予約より予約適用年月日を取得する
			JKKejbIdoRsvAccess jkIdoAc = new JKKejbIdoRsvAccess();
			List<CAANMsg> kk1681IdoList = jkIdoAc.getIdoRsvSvcKeiNo(kk0081Msg.getString(KK0081ETMsg.SVC_KEI_NO), JKKModelCommon.getOpeDate(inMsg));

			for (CAANMsg msg : kk1681IdoList)
			{
				// 異動予約詳細コードがオプション開始か判定
				if (IDO_RSV_DTL_OPSTA.equals(msg.getString(KK1681ETMsg.IDO_RSV_DTL_CD)))
				{
					// 異動予約の予約適用年月日を設定
					rule0088SvcStaYmd = msg.getString(KK1681ETMsg.RSV_APLY_YMD);
				}
			}
			
			// サービス契約の課金開始年月日を設定しているルールを呼び出す。
			
		}

		// 申込明細の申込年月日を取得
		// 申込明細番号をキーに申込明細をカレント検索する
		CAANMsg kk0021Msg = getCurrentKK0021(inMsg, kk0351Msg.getString(KK0351ETMsg.MSKM_DTL_NO));
		String mskmYmd = kk0021Msg.getString(KK0021ETMsg.MSKM_YMD);

		// 申込期間を取得する
		String mskmPeriod = this.getMskmPeriod(inMsg, mskmYmd, rule0088SvcStaYmd, svcChrgStaymd);
		// 申込期間が未設定または期間未定の場合はnullを返却（関連制約エラーとする）
		if (mskmPeriod == null || "0".equals(mskmPeriod))
		{
			return null;
		}
		// オプションサービス契約に紐付くサービス契約の料金グループを取得
		String prcGrpCd = kk0081Msg.getString(KK0081ETMsg.PRC_GRP_CD);
		
		instance.setSvc_cd(kk0081Msg.getString(KK0081ETMsg.SVC_CD));		        // サービスコードを設定する
		instance.setUpd_type("1");                                                  // 更新契機(開始時)を設定する
		instance.setOp_svc_cd(kk0351Msg.getString(KK0351ETMsg.OP_SVC_CD));          // オプションサービスコードを設定する
		instance.setSvc_sta_ymd(svcStaYmd);                                         // サービス開始年月日(オプションサービス契約カレント)を設定する
		instance.setBefor_svc_chrg_sta_ymd(svcChrgStaymd);
		instance.setMskm_period(mskmPeriod);
		instance.setPrc_grp_cd(prcGrpCd);
// ▽▽▽ ANK-3484-00-00 ADD START
		instance.setBefor_svc_chrg_end_ymd(null); // 引継元なしで設定
// △△△ ANK-3484-00-00 ADD END
		// 相関ルールを実行して結果を返却する
		return instance.getChrgStaYmd();
	}

	/**
	 * <p>
	 * プラン課金終了年月日を算出します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return 算出したプラン課金終了年月日
	 */
	public Object getChrgEndYmd(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0351C130Edit#getChrgEndYmd");

		// 課金開始年月日を取得
		String planChrgStaYmd = (String)getChrgStaYmdCancel(inMsg, inContext);

		// 課金開始年月日が取得できなかった場合
		if (null == planChrgStaYmd || "".equals(planChrgStaYmd))
		{
			return null;
		}

		// 課金開始年月日から1日前の日付を設定する		
		planChrgStaYmd = JKKModelCommon.addDay(planChrgStaYmd, -1);

		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JKKejbEKK0351C130Edit#getChrgEndYmd");

		return planChrgStaYmd;
	}

	/**
	 * <p>
	 * 申込期間を取得する
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param mskmYmd 申込日
	 * @param svcStaYmd サービス開始日
	 * @param svcChrgStaymd サービス課金開始日
	 * @return 申込期間
	 */
	private String getMskmPeriod(CAANMsg inCBSMsg, String mskmYmd, String svcStaYmd, String svcChrgStaymd)
	{
		// 申込期間を取得
		JKKejbRule0088001 rule0088 = new JKKejbRule0088001(inCBSMsg);
		rule0088.setMskm_ymd(mskmYmd);
		rule0088.setSvc_sta_ymd(svcStaYmd);
		rule0088.setSvc_chrg_staymd(svcChrgStaymd);
		return rule0088.getMskmPeriodDef();
	}
	
	/**
	 * <p>
	 * オプションサービス契約のカレントを検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return 取得したオプションサービス契約
	 */
	private CAANMsg getCurrentKK0351(CAANMsg inMsg)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());
		inETMsg.set(KK0351ETMsg.OP_SVC_KEI_NO, inMsg.getString(EKK0351C130CBSMsg.OP_SVC_KEI_NO));
		inETMsg.set(KK0351ETMsg.RSV_APLY_YMD, JKKModelCommon.getOpeDate(inMsg));

		// オプションサービス契約のカレント検索を行う
		CAANMsg otEtMsg = new JKKejbKK0351DBABase().findByCurrent(inETMsg);

		if (null == otEtMsg)
		{
			return null;
		}

		return otEtMsg;
	}

	/**
	 * <p>
	 * オプションサービス契約のプライマリを検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return 取得したオプションサービス契約
	 */
	private CAANMsg getPrimaryKK0351(CAANMsg inMsg)
	{
		// プライマリ検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());
		inETMsg.set(KK0351ETMsg.OP_SVC_KEI_NO, inMsg.getString(EKK0351C130CBSMsg.OP_SVC_KEI_NO));
		inETMsg.set(KK0351ETMsg.GENE_ADD_DTM, inMsg.getString(EKK0351C130CBSMsg.GENE_ADD_DTM));
		inETMsg.set(KK0351ETMsg.MK_FLG, MK_FLG_YUKO);

		// オプションサービス契約のプライマリ検索を行う
		CAANMsg otEtMsg = new KK0351LE().findByPrimaryKey(inETMsg);

		if (null == otEtMsg)
		{
			return null;
		}

		return otEtMsg;
	}

	/**
	 * <p>
	 * 申込明細のカレントを検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param mskmDtlNo 検索対象となる申込明細番号
	 * @return 取得した申込明細
	 */
	private CAANMsg getCurrentKK0021(CAANMsg inMsg, Object mskmDtlNo)
	{

		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0021ETMsg.class.getName());
		inETMsg.set(KK0021ETMsg.MSKM_DTL_NO, mskmDtlNo);

		// 申込明細のカレント検索を行う
		return new JKKejbKK0021DBABase().findByCurrent(inETMsg);

	}

	/**
	 * <p>
	 * 申込のカレントを検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param mskmNo 検索対象となる申込番号
	 * @return 取得した申込
	 */
	private CAANMsg getCurrentKK0011(CAANMsg inMsg, Object mskmNo)
	{

		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0011ETMsg.class.getName());
		inETMsg.set(KK0011ETMsg.MSKM_NO, mskmNo);

		// 申込明細のカレント検索を行う
		return new JKKejbKK0011DBABase().findByCurrent(inETMsg);
	}
// ▽▽▽ ANK-3484-00-00 ADD START
	/**
	 * <p>
	 * オプションサービス契約のカレントを検索します
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return 取得したオプションサービス契約
	 */
	private CAANMsg getCurrentKK0361(CAANMsg inMsg)
	{
		// カレント検索用のメッセージを作成
		CAANMsg inETMsg = new CAANMsg(KK0361ETMsg.class.getName());
		inETMsg.set(KK0361ETMsg.OP_SVC_KEI_NO, inMsg.getString(EKK0351C130CBSMsg.OP_SVC_KEI_NO));

		// オプションサービス契約のカレント検索を行う
		CAANMsg otEtMsg = new JKKejbKK0361DBABase().findByCurrent(inETMsg);

		return otEtMsg;
	}
// △△△ ANK-3484-00-00 ADD END
}
