/*******************************************************************************
 *	All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************************
 *＜プログラム内容＞
 *  システム名		：eo顧客基幹システム
 *  モジュール名	：JKKejbKK0081SecProc
 *  ソースファイル名：JKKejbKK0081SecProc.java
 *  作成者			：富士通
 *  日付			：2011年12月05日
 *＜機能概要＞
 *  サービス契約に対する副次処理を行う部品です。
 *＜修正履歴＞
 *  バージョン	修正日		修正者		修正内容
 *  v1.00.00	2011/12/05	富士通		新規作成
 *  v4.00.00	2013/04/16	FJ)竹内		IT1-2012-0000903
 *  v5.00.00	2013/07/09	FJ)寺園		LT-2013-0000321
 *  v5.00.01	2013/07/16	FJ)竹内		LT-2012-0000520
 *  v8.00.00	2014/05/07	FJ)舩橋		OM-2014-0001666
 *  v9.00.00	2014/06/04	FJ)中野		ANK-2079-00-00
 *  v9.00.01	2014/06/20	FJ)中野		ANK-2079-00-00
 *  v12.00.00   2015/01/19  FJ)中山     OM-2015-0000081
 *  v33.00.00   2017/07/24  FJ)クウン   【ANK-2802-00-00】加入御礼書抽出における改善
 *  v32.00.00   2017/07/28  FJ)星野     OM-2017-0000708
*	v33.00.00	2017/09/09	FJ)星野		OM-2017-0000920
 ********************************************************************************/

package eo.ejb.common.db;

import java.util.HashMap;
import java.util.List;

import com.fujitsu.futurity.common.JCCWebAddTrnId;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANFinderException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;

import eo.common.util.JPCDateUtil;
import eo.common.util.JPCUtilCommon;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0081LE;
import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbm.entity.KK1681ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0081C180CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081C250CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0101C040CBSMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;
import eo.ejb.common.entity.JKKejbIdoRsvAccess;

/**
 * <p>
 * サービス契約に対する副次処理部品クラスです。
 * </p>
 * @author 富士通
 *
 */
public class JKKejbKK0081SecProc extends JKKejbKK0081DBABase
{
	//---------v33.00.00 ANK-2802-00-00_ADD START---------//	
	/**
	 * 申込情報更新・照会画面の更新時のサービスID
	 */
	public static final String SERCVICE_ID_MSKM_UPD_SHOKAI_KKSV0037 = "KKSV0037";
	
	/**
	 * サービス契約情報更新・照会（eo光テレビ）画面の更新時のサービスID
	 */
	public static final String SERCVICE_ID_SVCINFO_UPD_SHOKAI_EOTV_KKSV0169 = "KKSV0169";
	//---------v33.00.00 ANK-2802-00-00_ADD END-----------//

	/**
	 * コンストラクタです。
	 */
	public JKKejbKK0081SecProc()
	{
		super();
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く予約の取消、および自動予約取消ワークの登録を行います。
	 * </p>
	 * @param svcKeiNo 取り消し対象のサービス契約番号
	 * @param idoDiv 異動区分
	 * @param mskmDtlNo 申込明細番号
	 * @param opeDate 運用日付
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 * @param autoRsvClStatCd 自動予約取消状態コード("取消済"/"自動予約取消未実施"：予約取消を実施する/しない)
	 */
	public void cancelReserve(String svcKeiNo, String idoDiv, String mskmDtlNo,
			String opeDate, String updDtm, String updOpeAct, String autoRsvClStatCd)
	{
		// サービス契約スキーマの予約取消
		
		// 予約検索用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_YMD, opeDate);

		// 予約検索を行う
		CAANMsg[] retMsgList = super.findByReserve(inETMsg);

		// 取得した予約レコードを全て取り消す
		for (CAANMsg retMsg : retMsgList)
		{
			// 自動予約取消状態コードが"取消済"の場合のみ、予約取消実施
			if (JKKModelConst.AUTO_RSV_CL_STAT_CD_CL_ZM.equals(autoRsvClStatCd))
			{
				updateKK0081ClRsv(retMsg, opeDate, updDtm, updOpeAct);
			}
			// 自動予約取消ワークに登録します
			this.createKK2791GymSchema(retMsg, idoDiv, mskmDtlNo, updDtm, updOpeAct, autoRsvClStatCd);
		}

		// 異動予約スキーマの予約取消

		// 予約検索を行う
		List<CAANMsg> retList = new JKKejbIdoRsvAccess().getIdoRsvSvcKeiNo(svcKeiNo, opeDate);

		// 予約レコードが存在した場合は取り消す
		for (CAANMsg retIdoRsv : retList)
		{
			// 異動予約詳細コードが"サービス休止解除"の場合
			String idoRsvDtlCd = retIdoRsv.getString(KK1681ETMsg.IDO_RSV_DTL_CD);
			if (JKKModelConst.IDO_RSV_DTL_CD_SVC_PAUSE_RLS.equals(idoRsvDtlCd))
			{
				// 異動予約詳細コードが"サービス休止"の「異動予約」が存在しない場合、予約取消対象外
				if (!isExistsPauseRsv(retList))
				{
					continue;
				}
			}

			// ただし、申込明細番号が同一のものは処理しない
			if (mskmDtlNo != null && !mskmDtlNo.equals(retIdoRsv.getString(KK1681ETMsg.MSKM_DTL_NO)))
			{
				// 自動予約取消状態コードが"取消済"の場合のみ、予約取消実施
				if (JKKModelConst.AUTO_RSV_CL_STAT_CD_CL_ZM.equals(autoRsvClStatCd))
				{
					new JKKejbKK1681SecProc().updateKK1681ClRsv(retIdoRsv, opeDate, updDtm, updOpeAct);
				}
				// 自動予約取消ワークに登録します
				this.createKK2791IdoRsv(retIdoRsv, idoDiv, mskmDtlNo, updDtm, updOpeAct, autoRsvClStatCd);
			}
		}
	}

	/**
	 * <p>
	 * 入力の異動予約リストに、サービス休止の「異動予約」が存在するかどうか判定します。
	 * </p>
	 * @param kk1681MsgList 異動予約リスト
	 * @return true:サービス休止の「異動予約」が存在する場合、false:それ以外
	 */
	private boolean isExistsPauseRsv(List<CAANMsg> kk1681MsgList)
	{
		for (CAANMsg kk1681Msg : kk1681MsgList)
		{
			// 異動予約詳細コードが"サービス休止"の「異動予約」が存在する場合
			if (JKKModelConst.IDO_RSV_DTL_CD_SVC_PAUSE.equals(kk1681Msg.getString(KK1681ETMsg.IDO_RSV_DTL_CD)))
			{
				return true;
			}
		}

		return false;
	}

	/**
	 * <p>
	 * 自動予約取消ワークにサービス契約の予約情報を登録します
	 * </p>
	 * @param kk0081EtMsg ETメッセージ
	 * @param idoDiv 異動区分
	 * @param mskmDtlNo 申込明細番号
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 * @param autoRsvClStatCd 自動予約取消状態コード
	 */
	private void createKK2791GymSchema(CAANMsg kk0081EtMsg, String idoDiv, String mskmDtlNo, String updDtm, String updOpeAct, String autoRsvClStatCd)
	{
		// 自動予約取消ワークＤＢ操作部品のインスタンス化
		JKKejbKK2791ETDA kk2791etda = new JKKejbKK2791ETDA();

		// 取消契機異動区分
		kk2791etda.setCl_opty_ido_div(idoDiv);
		// 取消契機申込明細番号
		kk2791etda.setCl_opty_mskm_dtl_no(mskmDtlNo);
		// サービス契約番号
		kk2791etda.setSvc_kei_no(kk0081EtMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		// 予約契機異動区分
		kk2791etda.setRsv_opty_ido_div(kk0081EtMsg.getString(KK0081ETMsg.IDO_DIV));
		// 予約契機申込明細番号
		kk2791etda.setRsv_opty_mskm_dtl_no(kk0081EtMsg.getString(KK0081ETMsg.MSKM_DTL_NO));
		// 予約適用年月日
		kk2791etda.setRsv_aply_ymd(kk0081EtMsg.getString(KK0081ETMsg.RSV_APLY_YMD));
		// 各種スキーマ世代登録年月日時分秒
		kk2791etda.setVari_schma_gene_add_dtm(kk0081EtMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		// 予約適用コード
		kk2791etda.setRsv_aply_cd(kk0081EtMsg.getString(KK0081ETMsg.RSV_APLY_CD));
		// 登録年月日時分秒
		kk2791etda.setAdd_dtm(updDtm);
		// 登録オペレータアカウント
		kk2791etda.setAdd_opeacnt(updOpeAct);
		// 更新年月日時分秒
		kk2791etda.setUpd_dtm(updDtm);
		// 更新オペレータアカウント
		kk2791etda.setUpd_opeacnt(updOpeAct);

		// 自動予約取消ワークの登録
		kk2791etda.createKK2791(kk0081EtMsg, "KK0081", autoRsvClStatCd);
	}

	/**
	 * <p>
	 * 自動予約取消ワークに異動予約の予約情報を登録します
	 * </p>
	 * @param kk1681EtMsg ETメッセージ
	 * @param idoDiv 異動区分
	 * @param mskmDtlNo 申込明細番号
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 * @param autoRsvClStatCd 自動予約取消状態コード
	 */
	private void createKK2791IdoRsv(CAANMsg kk1681EtMsg, String idoDiv, String mskmDtlNo, String updDtm, String updOpeAct, String autoRsvClStatCd)
	{
		// 自動予約取消ワークＤＢ操作部品のインスタンス化
		JKKejbKK2791ETDA kk2791etda = new JKKejbKK2791ETDA();

		// 取消契機異動区分
		kk2791etda.setCl_opty_ido_div(idoDiv);
		// 取消契機申込明細番号
		kk2791etda.setCl_opty_mskm_dtl_no(mskmDtlNo);
		// 登録年月日時分秒
		kk2791etda.setAdd_dtm(updDtm);
		// 登録オペレータアカウント
		kk2791etda.setAdd_opeacnt(updOpeAct);
		// 更新年月日時分秒
		kk2791etda.setUpd_dtm(updDtm);
		// 更新オペレータアカウント
		kk2791etda.setUpd_opeacnt(updOpeAct);

		// 自動予約取消ワークの登録
		kk2791etda.createKK2791(kk1681EtMsg, "KK1681", autoRsvClStatCd);
	}

	/**
	 * <p>
	 * 該当の「サービス契約」を回復(または解約取消)する際に、予約適用年月日が到来済の予約を取り消します。
	 * </p>
	 * @param svcKeiNo 回復(または解約取消)対象のサービス契約番号
	 * @param opeDate 運用日付
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void cancelReserveForKaihk(String svcKeiNo, String opeDate, String updDtm, String updOpeAct)
	{
		// 予約検索を行う
		List<CAANMsg> kk1681MsgList = new JKKejbIdoRsvAccess().getIdoRsvSvcKeiNo(svcKeiNo, opeDate);

		// 予約取消対象となる「異動予約」(予約適用年月日が到来済、かつ予約未反映)リスト
		JKKejbKK1681SecProc kk1681sp = new JKKejbKK1681SecProc();
		kk1681MsgList = kk1681sp.getIdoRsvForKaihkJiRsvCl(kk1681MsgList, opeDate);
		for (CAANMsg kk1681Msg : kk1681MsgList)
		{
			kk1681sp.updateKK1681ClRsv(kk1681Msg, opeDate, updDtm, updOpeAct);

			// 該当の予約と同時に作成された各種契約のインスタンスを削除する。
			kk1681sp.deleteInstanceForRsvCl(kk1681Msg, opeDate, updDtm, updOpeAct);
		}
	}
	
//OM-2017-0000708対応 星野 ADD START 20170728
	/**
	 * <p>
	 * 該当の「サービス契約」を請求先情報併合または請求先情報分割する際に、予約適用年月日が到来済の予約を取り消します。
	 * </p>
	 * @param svcKeiNo 請求先情報併合または請求先情報分割対象のサービス契約番号
	 * @param kakinsTstaymd 課金先適用開始年月日
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void cancelReserveForSeikyBnktHeigo(String svcKeiNo, String kakinsTstaymd, String opeDate, String updDtm, String updOpeAct)
	{
		// 異動予約スキーマの予約取消

		// 予約検索を行う
		List<CAANMsg> retList = new JKKejbIdoRsvAccess().getIdoRsvSvcKeiNo(svcKeiNo, kakinsTstaymd);

		// 予約レコードが存在した場合は取り消す
		for (CAANMsg retIdoRsv : retList)
		{
			String idoDiv = retIdoRsv.getString(KK1681ETMsg.IDO_DIV);
			String idoRsvDtlCd = retIdoRsv.getString(KK1681ETMsg.IDO_RSV_DTL_CD);
			String idoRsvStatCd = retIdoRsv.getString(KK1681ETMsg.IDO_RSV_STAT_CD);
			String rsvAplyYmd = retIdoRsv.getString(KK1681ETMsg.RSV_APLY_YMD);
			// 異動区分が「請求先情報併合」「請求先情報分割」
			// 異動予約詳細コードが「請求契約併合・分割・変更」
			// 異動予約状態コードが「未反映」
			// 予約適用年月日≧課金先適用開始年月日（同日含む）
			if(
				(JKKModelConst.IDO_DIV_SEIKY_KEI_HEIGO.equals(idoDiv) || JKKModelConst.IDO_DIV_SEIKY_KEI_BNKT.equals(idoDiv) )
				&& JKKModelConst.IDO_RSV_DTL_CD_SIKYKEI_CHG.equals( idoRsvDtlCd )
				&& JKKModelConst.IDO_RSV_STAT_CD_MI_HANEI.equals( idoRsvStatCd )
				&& ( kakinsTstaymd != null && !"".equals(kakinsTstaymd) && JPCUtilCommon.isFutureDate(rsvAplyYmd, kakinsTstaymd, "1") )
			){
				// 予約取消
				new JKKejbKK1681SecProc().updateKK1681ClRsv(retIdoRsv, opeDate, updDtm, updOpeAct);
			}
		}
	}
	
//OM-2017-0000708対応 星野 ADD END 20170728

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く予約（該当の「サービス契約」レコードのうち、未来日での予約確定レコード）を解約します。
	 * </p>
	 * @param svcKeiNo 解約対象のサービス契約番号
	 * @param opeDate 運用日付
	 * @param svcEndymd サービス終了年月日
	 * @param svcDslKisanYmd サービス解約起算年月日
	 * @param svcDlreCd サービス解約理由コード
	 * @param svcDlreMemo サービス解約理由メモ
	 * @param hojinsvkeiHktgiSbtCd 法人サービス契約引継ぎ種別コード
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void dslRsvFixRec(String svcKeiNo, String opeDate,
			String svcEndymd, String svcDslKisanYmd, String svcDlreCd, String svcDlreMemo, String hojinsvkeiHktgiSbtCd,
			String updDtm, String updOpeAct)
	{
		/* ------------------------------------------------------------------------------------------------------------------------
		 * 予約中の強制解約、および住所変更予約中の解約の場合、回復時に予約情報を反映する必要があるため予約取消は行わない。
		 * ※ただし、未来日・予約確定レコードについては、予約適用年月日が到来した時点で、カレントレコードとなってしまうため、
		 *   以下の更新処理を行う。
		 * (1)予約解約(キャンセル)：解約時に予約レコードを"解約済"とする。
		 * (2)予約回復(キャンセル取消)：回復時に予約レコードを元のステータスに回復する。（現時点では、住所変更中の解約／回復に対してのみ実施する。）
		 * ------------------------------------------------------------------------------------------------------------------------ */
		
		// 該当の「サービス契約」レコードの予約確定レコードを取得する。
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_CD, JKKModelConst.RSV_APLY_CD_RSV_FIX);
		inETMsg.set(KK0081ETMsg.MK_FLG, JKKModelConst.MK_FLG_YK);

		CAANMsg[] retMsg = null;
		try
		{
			retMsg = new KK0081LE().findByCondition(inETMsg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 予約解約実行
		for (int i = 0; i < retMsg.length; i++)
		{
			// 予約適用年月日＞運用日付の予約確定レコードのみ解約する。
			if (JKKModelCommon.isFutureDate(retMsg[i].getString(KK0081ETMsg.RSV_APLY_YMD), opeDate, "0"))
			{
				updateKK0081DslRsv(retMsg[i], svcEndymd, svcDslKisanYmd, svcDlreCd, svcDlreMemo, hojinsvkeiHktgiSbtCd,
						updDtm, updOpeAct);
			}
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く予約（該当の「サービス契約」レコードのうち、未来日での予約確定レコード）を回復します。
	 * </p>
	 * @param svcKeiNo 回復対象のサービス契約番号
	 * @param opeDate 運用日付
	 * @param dslBfSvcKeiStat 解約前サービス契約ステータス
	 * @param kaihkYmd 回復年月日
	 * @param svcDslClYmd サービス解約取消年月日
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void kaihkRsvFixRec(String svcKeiNo, String opeDate,
			String dslBfSvcKeiStat, String kaihkYmd, String svcDslClYmd, String updDtm, String updOpeAct)
	{
		/* ------------------------------------------------------------------------------------------------------------------------
		 * 予約中の強制解約、および住所変更予約中の解約の場合、回復時に予約情報を反映する必要があるため予約取消は行わない。
		 * ※ただし、未来日・予約確定レコードについては、予約適用年月日が到来した時点で、カレントレコードとなってしまうため、
		 *   以下の更新処理を行う。
		 * (1)予約解約(キャンセル)：解約時に予約レコードを"解約済"とする。
		 * (2)予約回復(キャンセル取消)：回復時に予約レコードを元のステータスに回復する。（現時点では、住所変更中の解約／回復に対してのみ実施する。）
		 * ------------------------------------------------------------------------------------------------------------------------ */
		
		// 該当の「サービス契約」レコードの予約確定レコードを取得する。
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_CD, JKKModelConst.RSV_APLY_CD_RSV_FIX);
		inETMsg.set(KK0081ETMsg.MK_FLG, JKKModelConst.MK_FLG_YK);

		CAANMsg[] retMsg = null;
		try
		{
			retMsg = new KK0081LE().findByCondition(inETMsg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 予約回復実行
		for (int i = 0; i < retMsg.length; i++)
		{
			// 住所変更による予約以外は、予約回復の対象外
			if (!JKKModelConst.IDO_DIV_ADCHG_ADD.equals(retMsg[i].getString(KK0081ETMsg.IDO_DIV)))
			{
				continue;
			}
			
			// 予約適用年月日＞運用日付の予約確定レコードのみ回復する。
			if (JKKModelCommon.isFutureDate(retMsg[i].getString(KK0081ETMsg.RSV_APLY_YMD), opeDate, "0"))
			{
				updateKK0081KaihkRsv(retMsg[i], dslBfSvcKeiStat, kaihkYmd, svcDslClYmd, updDtm, updOpeAct);
			}
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く、サービス契約スキーマの予約を取り消します。
	 * </p>
	 * @param inMsg 予約検索の結果を保持するメッセージキャリア
	 * @param opeDate 運用日付
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	private void updateKK0081ClRsv(CAANMsg inMsg, String opeDate, String updDtm, String updOpeAct)
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());

		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, inMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, inMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		inETMsg.set(KK0081ETMsg.RSV_CL_YMD, opeDate);
		inETMsg.set(KK0081ETMsg.RSV_APLY_CD, JKKModelConst.RSV_APLY_CD_RSV_CL);
		inETMsg.set(KK0081ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0081ETMsg.UPD_OPEACNT, updOpeAct);

		// 更新を行う
		try
		{
			super.update(inETMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く、サービス契約スキーマの予約レコードを解約します。
	 * </p>
	 * @param inMsg 予約検索の結果を保持するメッセージキャリア
	 * @param svcEndymd サービス終了年月日
	 * @param svcDslKisanYmd サービス解約起算年月日
	 * @param svcDlreCd サービス解約理由コード
	 * @param svcDlreMemo サービス解約理由メモ
	 * @param hojinsvkeiHktgiSbtCd 法人サービス契約引継ぎ種別コード
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	private void updateKK0081DslRsv(CAANMsg inMsg,
			String svcEndymd, String svcDslKisanYmd, String svcDlreCd, String svcDlreMemo, String hojinsvkeiHktgiSbtCd,
			String updDtm, String updOpeAct)
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());

		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, inMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, inMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		// サービス契約ステータス
		inETMsg.set(KK0081ETMsg.SVC_KEI_STAT, JKKModelConst.SVC_KEI_STAT_DSL_ZM);
		// プラン終了年月日
		inETMsg.set(KK0081ETMsg.PLAN_ENDYMD, svcEndymd);
		// プラン課金終了年月日
		inETMsg.set(KK0081ETMsg.PLAN_CHRG_ENDYMD, JPCDateUtil.addDay(svcDslKisanYmd, -1));
		// サービス終了年月日
		inETMsg.set(KK0081ETMsg.SVC_ENDYMD, svcEndymd);
		// サービス課金終了年月日
		inETMsg.set(KK0081ETMsg.SVC_CHRG_ENDYMD, JPCDateUtil.addDay(svcDslKisanYmd, -1));
		// サービス解約起算年月日
		inETMsg.set(KK0081ETMsg.SVC_DSL_KISAN_YMD, svcDslKisanYmd);
		// サービス解約年月日
		inETMsg.set(KK0081ETMsg.SVC_DSL_YMD, svcEndymd);
		// サービス解約理由コード
		inETMsg.set(KK0081ETMsg.SVC_DLRE_CD, svcDlreCd);
		// サービス解約理由メモ
		inETMsg.set(KK0081ETMsg.SVC_DLRE_MEMO, svcDlreMemo);
		// 法人サービス契約引継ぎ種別コード
		inETMsg.set(KK0081ETMsg.HOJINSVKEI_HKTGI_SBT_CD, hojinsvkeiHktgiSbtCd);
		inETMsg.set(KK0081ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0081ETMsg.UPD_OPEACNT, updOpeAct);
		
		// 更新を行う
		try
		{
			super.update(inETMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く、サービス契約スキーマの予約レコードを回復します。
	 * </p>
	 * @param inMsg 予約検索の結果を保持するメッセージキャリア
	 * @param dslBfSvcKeiStat 解約前サービス契約ステータス
	 * @param kaihkYmd 回復年月日
	 * @param svcDslClYmd サービス解約取消年月日
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	private void updateKK0081KaihkRsv(CAANMsg inMsg, String dslBfSvcKeiStat, String kaihkYmd, String svcDslClYmd,
			String updDtm, String updOpeAct)
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());

		// 終了年月日初期値
		String initEndYmd = null;
		if (JKKModelConst.SVC_KEI_STAT_SVCTK_CHU.equals(dslBfSvcKeiStat)
				|| JKKModelConst.SVC_KEI_STAT_PAUSE_STP_CHU.equals(dslBfSvcKeiStat))
		{
			// "サービス提供中"または"休止・中断中"に回復させる場合、終了年月日に最大日付を設定
			initEndYmd = JKKModelConst.DATE_MAX;
		}

		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, inMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, inMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		// サービス契約ステータス
		inETMsg.set(KK0081ETMsg.SVC_KEI_STAT, dslBfSvcKeiStat);
		// プラン終了年月日
		inETMsg.set(KK0081ETMsg.PLAN_ENDYMD, initEndYmd);
		// プラン課金終了年月日
		inETMsg.set(KK0081ETMsg.PLAN_CHRG_ENDYMD, initEndYmd);
		// プラン終了種別コード
		inETMsg.setNull(KK0081ETMsg.PLAN_END_SBT_CD);
		// サービス終了年月日
		inETMsg.set(KK0081ETMsg.SVC_ENDYMD, initEndYmd);
		// サービス課金終了年月日
		inETMsg.set(KK0081ETMsg.SVC_CHRG_ENDYMD, initEndYmd);
		// サービス解約起算年月日
		inETMsg.setNull(KK0081ETMsg.SVC_DSL_KISAN_YMD);
		// サービス解約年月日
		inETMsg.setNull(KK0081ETMsg.SVC_DSL_YMD);
		// サービス解約理由コード
		inETMsg.setNull(KK0081ETMsg.SVC_DLRE_CD);
		// サービス解約理由メモ
		inETMsg.setNull(KK0081ETMsg.SVC_DLRE_MEMO);
		// サービス解約手続完了フラグ
		inETMsg.setNull(KK0081ETMsg.SVC_DSL_TTDKI_FIN_FLG);
		// 回復年月日
		if (kaihkYmd != null && !"".equals(kaihkYmd))
		{
			inETMsg.set(KK0081ETMsg.KAIHK_YMD, kaihkYmd);
		}
		// サービス解約取消年月日
		if (svcDslClYmd != null && !"".equals(svcDslClYmd))
		{
			inETMsg.set(KK0081ETMsg.SVC_DSL_CL_YMD, svcDslClYmd);
		}
		inETMsg.set(KK0081ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0081ETMsg.UPD_OPEACNT, updOpeAct);

		// 更新を行う
		try
		{
			super.update(inETMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く予約（該当の「サービス契約」レコードのうち、未来日での予約確定レコード）を停止/解除します。
	 * </p>
	 * @param svcKeiNo 停止/解除対象のサービス契約番号
	 * @param rsvAplyCd 停止/解除対象のサービス契約ステータス
	 * @param opeDate 運用日付
	 * @param svcStpymd サービス停止/解除年月日
	 * @param svcStpCd サービス停止/解除理由コード
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	public void stpSvcKeiRec(String svcKeiNo, String rsvAplyCd, String opeDate, String svcStpymd, String svcStpCd, 
			String updDtm, String updOpeAct)
	{
		// 該当の「サービス契約」レコードの予約確定レコードを取得する。
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_CD, JKKModelConst.RSV_APLY_CD_RSV_FIX);
		inETMsg.set(KK0081ETMsg.MK_FLG, JKKModelConst.MK_FLG_YK);

		CAANMsg[] retMsg = null;
		try
		{
			retMsg = new KK0081LE().findByCondition(inETMsg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}

		// 予約停止/解除実行
		for (int i = 0; i < retMsg.length; i++)
		{
			// 予約適用年月日＞運用日付の予約確定レコードのみ停止/解除する。
			if (JKKModelCommon.isFutureDate(retMsg[i].getString(KK0081ETMsg.RSV_APLY_YMD), opeDate, "0"))
			{
				updateKK0081StpSvcKei(retMsg[i], rsvAplyCd, svcStpymd, svcStpCd, updDtm, updOpeAct);
			}
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く、サービス契約スキーマの予約レコードを停止/解除します。
	 * </p>
	 * @param inMsg 予約検索の結果を保持するメッセージキャリア
	 * @param rsvAplyCd 停止/解除対象のサービス契約ステータス
	 * @param svcStpymd サービス停止/解除年月日
	 * @param svcStpCd サービス停止/解除理由コード
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 */
	private void updateKK0081StpSvcKei(CAANMsg inMsg, String rsvAplyCd, String svcStpymd, String svcStpCd, String updDtm, 
			String updOpeAct)
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());

		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, inMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, inMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		// サービス契約ステータス
		inETMsg.set(KK0081ETMsg.SVC_KEI_STAT, rsvAplyCd);

		// 停止中は停止年月日、停止理由コードを更新し、停止解除年月日、停止理由解除コードを空白にする。
		if (JKKModelConst.SVC_KEI_STAT_STP_CHU.equals(rsvAplyCd))
		{
			// サービス停止年月日
			inETMsg.set(KK0081ETMsg.SVC_STP_YMD, svcStpymd);
			// サービス停止理由コード
			inETMsg.set(KK0081ETMsg.SVC_STP_RSN_CD, svcStpCd);
			// サービス停止解除年月日
			inETMsg.setNull(KK0081ETMsg.SVC_STP_RLS_YMD);
			// サービス停止理由解除コード
			inETMsg.setNull(KK0081ETMsg.SVC_STP_RLS_RSN_CD);
		}
		// 停止中以外は停止解除年月日、停止理由解除コードを更新する。
		else
		{
			// サービス停止解除年月日
			inETMsg.set(KK0081ETMsg.SVC_STP_RLS_YMD, svcStpymd);
			// サービス停止理由解除コード
			inETMsg.set(KK0081ETMsg.SVC_STP_RLS_RSN_CD, svcStpCd);
		}

		inETMsg.set(KK0081ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0081ETMsg.UPD_OPEACNT, updOpeAct);
		
		// 更新を行う
		try
		{
			super.update(inETMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}
	
	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付く異動予約を検索し、解約予約が存在すれば予約取消フラグ
	 * を設定する。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param svcKeiNo 取り消し対象のサービス契約番号
	 * @param opeDate 運用日付
	 */
	public void idoRsvExisCheck(CAANMsg inCBSMsg, String svcKeiNo, String opeDate)
	{	
		// 予約検索
		List<CAANMsg> retList = new JKKejbIdoRsvAccess().getIdoRsvSvcKeiNo(svcKeiNo, opeDate);

		// 予約レコードが存在した場合、処理対象とする
		for (CAANMsg retIdoRsv : retList)
		{
			// サービス契約の異動区分が「解約」以外の場合、対象外とする
			String idoDivCd = retIdoRsv.getString(KK1681ETMsg.IDO_DIV);
			if (!JKKModelConst.IDO_DIV_DSL.equals(idoDivCd))
			{
				continue;
			}
			// 返却項目メッセージ生成
			inCBSMsg.set(EKK0081C180CBSMsg.RSV_CL_FLG, JKKModelConst.RSV_CL_FLG_ON);
		}	
	}

//OM-2015-0000081 ADD START

	/**
	 * <p>
	 * 指定されたサービス契約番号に紐付くサービス契約スキーマの予約レコードの審査結果コードの更新を行います。
	 * </p>
	 * @param svcKeiNo サービス契約番号
	 * @param skekkaCd 審査結果コード
	 * @param opeDate 運用日付
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 */
	//---------v33.00.00 ANK-2802-00-00_DEL START---------//
	//public void updateRsvSkkekaCd(String svcKeiNo, String skekkaCd, String opeDate, String updDtm, String updOpeAct)
	//---------v33.00.00 ANK-2802-00-00_DEL START---------//
	//---------v33.00.00 ANK-2802-00-00_ADD START---------//
	public void updateRsvSkkekaCd(String svcKeiNo, String skekkaCd, String opeDate, String updDtm, String updOpeAct, CAANMsg inCBSMsg)
	//---------v33.00.00 ANK-2802-00-00_ADD END-----------//
	{
		// 予約検索用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());
		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
		inETMsg.set(KK0081ETMsg.RSV_APLY_YMD, opeDate);

		// 予約検索を行う
		CAANMsg[] retMsgList = super.findByReserve(inETMsg);

		// 取得した予約レコードの最終レコードの審査結果コードを更新する
		if (retMsgList.length > 0)
		{
			//---------v33.00.00 ANK-2802-00-00_DEL START---------//
			//updateKK0081SkkekaCd(retMsgList[retMsgList.length - 1], skekkaCd, updDtm, updOpeAct);
			//---------v33.00.00 ANK-2802-00-00_DEL START---------//
			//---------v33.00.00 ANK-2802-00-00_ADD START---------//
			updateKK0081SkkekaCd(retMsgList[retMsgList.length - 1], skekkaCd, updDtm, updOpeAct, inCBSMsg);
			//---------v33.00.00 ANK-2802-00-00_ADD END-----------//
		}
	}

	/**
	 * <p>
	 * 指定されたサービス契約番号、世代登録年月日時分秒に紐つくサービス契約スキーマの審査結果コードを更新します。
	 * </p>
	 * @param inMsg 検索の結果を保持するメッセージキャリア
	 * @param skekkaCd 審査結果コード
	 * @param updDtm 更新年月日時分秒
	 * @param updOpeAct 更新オペレータアカウント
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 */
	//---------v33.00.00 ANK-2802-00-00_DEL START---------//
//	private void updateKK0081SkkekaCd(CAANMsg inMsg, String skekkaCd, String updDtm, String updOpeAct)
	//---------v33.00.00 ANK-2802-00-00_DEL START---------//
	//---------v33.00.00 ANK-2802-00-00_ADD START---------//
	private void updateKK0081SkkekaCd(CAANMsg inMsg, String skekkaCd, String updDtm, String updOpeAct, CAANMsg inCBSMsg)
	//---------v33.00.00 ANK-2802-00-00_ADD END-----------//
	{
		// 更新用メッセージ作成
		CAANMsg inETMsg = new CAANMsg(KK0081ETMsg.class.getName());

		inETMsg.set(KK0081ETMsg.SVC_KEI_NO, inMsg.getString(KK0081ETMsg.SVC_KEI_NO));
		inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, inMsg.getString(KK0081ETMsg.GENE_ADD_DTM));
		inETMsg.set(KK0081ETMsg.SKEKKA_CD, skekkaCd);
		inETMsg.set(KK0081ETMsg.UPD_DTM, updDtm);
		inETMsg.set(KK0081ETMsg.UPD_OPEACNT, updOpeAct);

		//---------v33.00.00 ANK-2802-00-00_ADD START---------//	
		// 共通メッセージからサービス呼び出し元の区分を取得する
		HashMap<String, Object> commonMsg = JCCWebAddTrnId.get(JCMConstants.ADD_TRN_ID_MESSAGE_COMMON_MAP);

		// 呼び出し元サービスID
		String serviceId = (String)commonMsg.get(JCMConstants.USECASE_ID_KEY);
		
		// 遷移元画面：サービス契約情報更新・照会（eo光テレビ）画面（KKW00129)の場合、下記の項目を更新
		if (SERCVICE_ID_SVCINFO_UPD_SHOKAI_EOTV_KKSV0169.equals(serviceId))
		{
			// 項目名称設定
			//審査結果詳細コード
			inETMsg.set(KK0081ETMsg.SKEKKA_DTL_CD, inCBSMsg.getString(EKK0101C040CBSMsg.SKEKKA_DTL_CD));
			//審査結果送信コード
			inETMsg.set(KK0081ETMsg.SKEKKA_SEND_CD, inCBSMsg.getString(EKK0101C040CBSMsg.SKEKKA_SEND_CD));
		}
		// 遷移元画面：申込情報更新・照会（eo光テレビ）画面（KKW00127)の場合、下記の項目を更新
		if (SERCVICE_ID_MSKM_UPD_SHOKAI_KKSV0037.equals(serviceId))
		{
			// 項目名称設定
			//支払い方法継続フラグ
			inETMsg.set(KK0081ETMsg.PAYWAY_KEIZOKU_FLG, inCBSMsg.getString(EKK0101C040CBSMsg.PAYWAY_KEIZOKU_FLG));
		}
		//---------v33.00.00 ANK-2802-00-00_ADD END-----------//
		// 更新を行う
		try
		{
			super.update(inETMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}

//OM-2015-0000081 ADD END
	
// OM-2017-0000920対応 20170920 星野 ADD START
	/**
	 * サービス契約のお客様変更の登録（未来日レコード分）を行います。
	 * @param inCbsMsg CBSメッセージ
	 * @param opSvcKeiNo サービス契約番号
	 * @param sysid SYSID
	 * @param rsvAplyYmd 予約適用年月日
	 */
	public void svcKeiCustChgUpdateFuture(CAANMsg inCbsMsg, String svcKeiNo, String sysid, String rsvAplyYmd) {
		try 
		{
			// 予約検索用メッセージ作成
			CAANMsg searchETMsg = new CAANMsg(KK0081ETMsg.class.getName());
			searchETMsg.set(KK0081ETMsg.SVC_KEI_NO, svcKeiNo);
			searchETMsg.set(KK0081ETMsg.RSV_APLY_YMD, rsvAplyYmd);

			// 予約検索を行う
			CAANMsg[] retMsgList = super.findByReserve(searchETMsg);
			
			if(retMsgList == null){
				return;
			}			

			for(CAANMsg retKK0081: retMsgList){

				if (retKK0081 == null)
				{
					return;
				}
	
				// サービス契約お客様変更処理を行う。
				CAANMsg inETMsg = new CAANMsg(KK0351ETMsg.class.getName());

				inETMsg.set(KK0081ETMsg.SVC_KEI_NO, retKK0081.getString(KK0081ETMsg.SVC_KEI_NO));
				inETMsg.set(KK0081ETMsg.GENE_ADD_DTM, retKK0081.getString(KK0081ETMsg.GENE_ADD_DTM));
				
				inETMsg.set(KK0081ETMsg.SYSID, sysid);
				
				inETMsg.set(KK0081ETMsg.UPD_DTM, inCbsMsg.getString(EKK0081C250CBSMsg.OPERATEDATETIME));
				inETMsg.set(KK0081ETMsg.UPD_OPEACNT, inCbsMsg.getString(EKK0081C250CBSMsg.UPD_OPEACNT));
				
				super.update(inETMsg);
			}
		} 
		catch (CAANFinderException e1) 
		{
			throw new CAANRuntimeException(e1);
		}
	}
// OM-2017-0000920対応 20170920 星野 ADD END
	
}
