/********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：JKKAdchgWrisvcCancelCC
 *  ソースファイル名：JKKAdchgWrisvcCancelCC.java
 *  作成者          ：FJ
 *  日付            ：2013年06月12日
 *＜機能概要＞
 *  割引サービスキャンセル(住所変更)CC部品
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v1.00.00    2013/06/12  FJ          新規作成
 *  v8.00.00    2014/04/15  FJ)金田     OM-2014-0000350対応
 *  v8.00.01    2014/04/15  FJ)金田     OM-2014-0000350対応
 *  v9.00.00	2014/04/30  FJ)北谷     ANK-2056-00-00対応
 *  v9.01.00	2014/06/19  FJ)北谷     IT2-2014-0000262対応
 * v50.00.00    2020/07/07  FJ)三原     【ANK-3754-00-00】トビラフォン対応
 ********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKAdchgConstCC;
import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.sun.enterprise.tools.common.util.StringUtils;

import eo.ejb.cbs.cbsmsg.EKK0451A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0451B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0451C020CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451C030CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0451C070CBSMsg;

public class JKKAdchgWrisvcCancelCC extends AbstractCommonComponent {

	/** セッションハンドル保持域 */
	private static ThreadLocal<SessionHandle> keepSesHandle = new ThreadLocal<SessionHandle>()
	{
		// 保持域への設定はinitialValue()ではなくset()を使用する為、
		// initialValue()は実装しない
	};

	/**
	 * コンストラクタ.
	 * <br>
	 */
	public JKKAdchgWrisvcCancelCC() {
	}
	

	/**
	 * 割引サービスを論理削除します。
	 * <br>
	 * @param   handle     セッションマネージャなどを持ったハンドル情報
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Throwable  例外が発生した場合
	 * @return  リクエストパラメータ(param)に戻り値を追加して返却する
	 */
	public IRequestParameterReadWrite cancel(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable {
// OM-2013-0004303対応 20131120 星野 ADD START
		try {
// OM-2013-0004303対応 20131120 星野 ADD END
			// セッションハンドルをローカル変数に保持
			keepSesHandle.set( handle );
	
			// 事前準備
			HashMap<String, String> condMap = new HashMap<String, String>();
			HashMap<String, Object> reqMap;
			Map<?, ?> resMap;
	
			// 住所情報変更初期表示情報取得コモンコンポーネント
			// マッピングクラスインスタンスを取得
			JKKAdchgMapperCC mapper = JKKAdchgMapperCC.getInstance();
	
			// SCリクエストInvokerを取得
			ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
			HashMap<String, Object> paramMap = (HashMap<String, Object>)( param.getData(fixedText) );
			
			//IT2-2014-0000262 2014/06/19 mod start
//			// サービス契約番号
//			String svcKeiNo = (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_SVC_KEI_NO);
//			
//			if (StringUtils.isEmpty(svcKeiNo)) {
//				return param;
//			}
//			
//			// 割引サービス一覧照会
//			condMap.put( JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNo);
//			reqMap = mapper.setEKK0451B001( param, fixedText, condMap );
//			resMap = scCall.run( reqMap, keepSesHandle.get() );
//			ArrayList<HashMap<String, Object>> kk0451_b010_list = mapper.getEKK0451B001( param, fixedText, resMap );
//			mapper.scResultCheck( param );
//			
//			if (kk0451_b010_list.size() == 0) {
//				
//				// 取得できない場合、処理終了
//				return param;
//			}
//			
//			for (HashMap<String, Object> kk0451_b010_map : kk0451_b010_list)
//			{
//				String wriSvcKeiNo = (String)kk0451_b010_map.get(EKK0451B001CBSMsg1List.WRIB_SVC_KEI_NO);
//				
//				// 割引サービス一意照会
//				condMap.clear();
//				condMap.put( JKKAdchgMapperCC.COND_KEY_WRIB_SVC_KEI_NO, wriSvcKeiNo);
//				condMap.put( JKKAdchgMapperCC.COND_KEY_OPEDATE, "20991231");
//				reqMap = mapper.setEKK0451A010( param, fixedText, condMap );
//				resMap = scCall.run( reqMap, keepSesHandle.get() );
//				HashMap<String, Object> kk0451_a010_map = mapper.getEKK0451A010( param, fixedText, resMap );
//				mapper.scResultCheck( param );
//				
//				String idoDiv = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.IDO_DIV);
//				String wriState = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.WRIB_SVC_KEI_STAT);
//				
//				// ANK-2056-00-00 2014/04/28 start
//				String wriSvcCd = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.WRIB_SVC_CD);
//				// ANK-2056-00-00 2014/04/28 end
//				
//// OM-2014-0000350 2014.04.11 Y.Kanata MOD START
////				if ("00019".equals(idoDiv) && "010".equals(wriState)) {
////				
////					String mskmDtl = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.MSKM_DTL_NO);
////					String updDtm = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.LAST_UPD_DTM);
//				if ("00019".equals(idoDiv)) {
//					// 各サービスの申込明細番号から今回キャンセルの住所変更にて追加された割引か判断する。
//					String mskmDtl = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.MSKM_DTL_NO);
//					boolean isMskmCurAdchg = checkMskmDtlNo(paramMap, mskmDtl);
//					// 今回キャンセル住所変更にて追加された割引ならキャンセル／解約を行う。
//					if (isMskmCurAdchg) {
//						
//						String updDtm = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.LAST_UPD_DTM);
//						
//						// 010：受付済, 020：照査済 の場合はキャンセルを行う
//						if ("020".compareTo(wriState) >= 0) {
//// 以下、条件追加によるインデント変更
//// OM-2014-0000350 2014.04.11 Y.Kanata MOD END
//							
//							// 割引サービスキャンセル
//							condMap.clear();
//							condMap.put( EKK0451C070CBSMsg.WRIB_SVC_KEI_NO, wriSvcKeiNo);
//							condMap.put( EKK0451C070CBSMsg.MSKM_DTL_NO, mskmDtl);
//							condMap.put( EKK0451C070CBSMsg.SVC_CANCEL_RSN_CD, "01");
//							condMap.put( EKK0451C070CBSMsg.IDO_DIV, "00019");
//							condMap.put( EKK0451C070CBSMsg.WRIB_DSL_CNCL_OPTY_CD, "1");
//							condMap.put( EKK0451C070CBSMsg.UPD_DTM_BF, updDtm);
//							
//							reqMap = mapper.setEKK0451C070( param, fixedText, condMap );
//							resMap = scCall.run( reqMap, keepSesHandle.get() );
//							mapper.getEKK0451C070( param, fixedText, resMap );
//							mapper.scResultCheck( param );
//							
//// OM-2014-0000350 2014.04.11 Y.Kanata ADD START
//// 条件追加によるインデント変更ここまで
//						// 030：締結済, 100：サービス提供中 の場合は解約を行う
//						} else if ("020".compareTo(wriState) < 0 && " ".compareTo(wriState) >= 0
//						// ANK-2056-00-00 2014/04/28 start
//						// OPパックの場合、割引サービス契約ステータスが100の場合は住所変更キャンセル対象外
//							&& !"W00000007".equals(wriSvcCd) && !"W00000008".equals(wriSvcCd)
//						// ANK-2056-00-00 2014/04/28 end
//						) {
//							String svcChrgStaYmd = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.SVC_CHRG_STAYMD);
//							// 割引サービス解約
//							dslWrbk(param, fixedText, mapper, scCall, updDtm, wriSvcKeiNo, mskmDtl, svcChrgStaYmd);
//						}
//					}
//// OM-2014-0000350 2014.04.11 Y.Kanata ADD END
//				}
//				
//			}
			
			// サービス契約番号
			//String svcKeiNo = (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_SVC_KEI_NO);
			String netSvcKeiNo = (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_NET_SVC_KEI_NO);
			String telSvcKeiNo = (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_TEL_SVC_KEI_NO);
			String tvSvcKeiNo = (String)paramMap.get(JKKAdchgConstCC.PARAM_KEY_TV_SVC_KEI_NO);
			
			ArrayList<String> svcKeiNoList = new ArrayList<String>();
			if (!StringUtils.isEmpty(netSvcKeiNo)) {
				svcKeiNoList.add(netSvcKeiNo);
			}
			if (!StringUtils.isEmpty(telSvcKeiNo)) {
				svcKeiNoList.add(telSvcKeiNo);
			}
			if (!StringUtils.isEmpty(tvSvcKeiNo)) {
				svcKeiNoList.add(tvSvcKeiNo);
			}
			
			if (svcKeiNoList.size()==0) {
				return param;
			}
			
			//ネット、電話、TVのサービス契約について割引をキャンセル
			for(String svcKeiNo : svcKeiNoList){
			
				// 割引サービス一覧照会
				condMap.put( JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNo);
				reqMap = mapper.setEKK0451B001( param, fixedText, condMap );
				resMap = scCall.run( reqMap, keepSesHandle.get() );
				ArrayList<HashMap<String, Object>> kk0451_b010_list = mapper.getEKK0451B001( param, fixedText, resMap );
				mapper.scResultCheck( param );

				if (kk0451_b010_list.size() == 0) {

					// 取得できない場合、処理終了
					return param;
				}

				for (HashMap<String, Object> kk0451_b010_map : kk0451_b010_list)
				{
					String wriSvcKeiNo = (String)kk0451_b010_map.get(EKK0451B001CBSMsg1List.WRIB_SVC_KEI_NO);

					// 割引サービス一意照会
					condMap.clear();
					condMap.put( JKKAdchgMapperCC.COND_KEY_WRIB_SVC_KEI_NO, wriSvcKeiNo);
					condMap.put( JKKAdchgMapperCC.COND_KEY_OPEDATE, "20991231");
					reqMap = mapper.setEKK0451A010( param, fixedText, condMap );
					resMap = scCall.run( reqMap, keepSesHandle.get() );
					HashMap<String, Object> kk0451_a010_map = mapper.getEKK0451A010( param, fixedText, resMap );
					mapper.scResultCheck( param );

					String idoDiv = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.IDO_DIV);
					String wriState = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.WRIB_SVC_KEI_STAT);

					// ANK-2056-00-00 2014/04/28 start
					String wriSvcCd = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.WRIB_SVC_CD);
					// ANK-2056-00-00 2014/04/28 end

					// OM-2014-0000350 2014.04.11 Y.Kanata MOD START
					//				if ("00019".equals(idoDiv) && "010".equals(wriState)) {
					//				
					//					String mskmDtl = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.MSKM_DTL_NO);
					//					String updDtm = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.LAST_UPD_DTM);
					if ("00019".equals(idoDiv)) {
						// 各サービスの申込明細番号から今回キャンセルの住所変更にて追加された割引か判断する。
						String mskmDtl = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.MSKM_DTL_NO);
						boolean isMskmCurAdchg = checkMskmDtlNo(paramMap, mskmDtl);
						// 今回キャンセル住所変更にて追加された割引ならキャンセル／解約を行う。
						if (isMskmCurAdchg) {

							String updDtm = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.LAST_UPD_DTM);

							// 010：受付済, 020：照査済 の場合はキャンセルを行う
							if ("020".compareTo(wriState) >= 0) {
								// 以下、条件追加によるインデント変更
								// OM-2014-0000350 2014.04.11 Y.Kanata MOD END

								// 割引サービスキャンセル
								condMap.clear();
								condMap.put( EKK0451C070CBSMsg.WRIB_SVC_KEI_NO, wriSvcKeiNo);
								condMap.put( EKK0451C070CBSMsg.MSKM_DTL_NO, mskmDtl);
								condMap.put( EKK0451C070CBSMsg.SVC_CANCEL_RSN_CD, "01");
								condMap.put( EKK0451C070CBSMsg.IDO_DIV, "00019");
								condMap.put( EKK0451C070CBSMsg.WRIB_DSL_CNCL_OPTY_CD, "1");
								condMap.put( EKK0451C070CBSMsg.UPD_DTM_BF, updDtm);

								reqMap = mapper.setEKK0451C070( param, fixedText, condMap );
								resMap = scCall.run( reqMap, keepSesHandle.get() );
								mapper.getEKK0451C070( param, fixedText, resMap );
								mapper.scResultCheck( param );

								// OM-2014-0000350 2014.04.11 Y.Kanata ADD START
								// 条件追加によるインデント変更ここまで
								// 030：締結済, 100：サービス提供中 の場合は解約を行う
							} else if ("020".compareTo(wriState) < 0 && " ".compareTo(wriState) >= 0
									// ANK-2056-00-00 2014/04/28 start
									// OPパックの場合、割引サービス契約ステータスが100の場合は住所変更キャンセル対象外
									// ANK-3754-00-00 MOD START
									//&& !"W00000007".equals(wriSvcCd) && !"W00000008".equals(wriSvcCd)
									&& !"W00000007".equals(wriSvcCd) && !"W00000008".equals(wriSvcCd) && !"W00000023".equals(wriSvcCd)
									// ANK-3754-00-00 MOD END
									// ANK-2056-00-00 2014/04/28 end
							) {
								String svcChrgStaYmd = (String)kk0451_a010_map.get(EKK0451A010CBSMsg1List.SVC_CHRG_STAYMD);
								// 割引サービス解約
								dslWrbk(param, fixedText, mapper, scCall, updDtm, wriSvcKeiNo, mskmDtl, svcChrgStaYmd);
							}
						}
						// OM-2014-0000350 2014.04.11 Y.Kanata ADD END
					}

				}

			}
			//IT2-2014-0000262 2014/06/19 mod end
			
			return param;
// OM-2013-0004303対応 20131120 星野 ADD START
		} finally {

			// ・セッションハンドル保持域
			if(keepSesHandle.get() != null){
				keepSesHandle.remove();
			}
		}

// OM-2013-0004303対応 20131120 星野 ADD END
		
	}

// OM-2014-0000350 2014.04.11 Y.Kanata ADD START
	/**
	 * 申込明細番号を用いて今回キャンセルの住所変更で発生したか判断する
	 */
	private boolean checkMskmDtlNo(HashMap<String, Object> paramMap, String wriMskmDtlNo) {
		// パラメータチェック
		if (StringUtils.isEmpty(wriMskmDtlNo)) {
			return false;
		}
		
		// Web層から連携の申込明細番号を用いて照合を行う。
		String netMskmDtlNo = (String)paramMap.get("netMskmDtlNo");
		String TelMskmDtlNo = (String)paramMap.get("telMskmDtlNo");
		String TvMskmDtlNo = (String)paramMap.get("tvMskmDtlNo");
		
		// 何れかの申込明細番号と一致する場合は今回キャンセルの住所変更で発生したと判断する。
		if (wriMskmDtlNo.equals(netMskmDtlNo)
				|| wriMskmDtlNo.equals(TelMskmDtlNo)
				|| wriMskmDtlNo.equals(TvMskmDtlNo)
				) {
			return true;
		}
		// 一致なしの場合、他の異動で発生したと判断する。
		return false;
	}
	
	/**
	 * 割引サービスを解約する
	 * 
	 * @param param
	 * @param fixedText
	 * @param mapper
	 * @param scCall
	 * @param updDtm
	 * @param wriSvcKeiNo
	 * @param mskmDtl
	 * @return
	 * @throws Throwable
	 */
	private IRequestParameterReadWrite dslWrbk(
			IRequestParameterReadWrite param
			, String fixedText
			, JKKAdchgMapperCC mapper
			, ServiceComponentRequestInvoker scCall
			, String updDtm
			, String wriSvcKeiNo
			, String mskmDtl
			, String svcChrgStaYmd
			) throws Throwable{
		
		// 事前準備
		HashMap<String, Object> condiMap = new HashMap<String, Object>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		String opeDate = JCCBPCommon.getOpeDate(null);
		String chrgEndYmd = addYYYYMMDD(JCCBPCommon.getOpeDate(null), -1);
		
		// 割引サービス解約
		condiMap.clear();
		// 割引サービス契約番号
		condiMap.put( EKK0451C020CBSMsg.WRIB_SVC_KEI_NO, wriSvcKeiNo);
		// 申込明細番号
		condiMap.put( EKK0451C020CBSMsg.MSKM_DTL_NO, mskmDtl);
		// サービス終了年月日
		condiMap.put( EKK0451C020CBSMsg.SVC_ENDYMD, opeDate);
		// サービス課金終了年月日
// OM-2014-0000350 2014.04.15 Y.Kanata MOD START
//		condiMap.put( EKK0451C020CBSMsg.SVC_CHRG_ENDYMD, chrgEndYmd);
		condiMap.put( EKK0451C020CBSMsg.SVC_CHRG_ENDYMD, opeDate);
// OM-2014-0000350 2014.04.15 Y.Kanata MOD END
		// サービス解約年月日
		condiMap.put( EKK0451C020CBSMsg.SVC_DSL_YMD, opeDate);
		// サービス解約理由コード
		condiMap.put( EKK0451C020CBSMsg.SVC_DLRE_CD, "01");
		// 異動区分
		condiMap.put( EKK0451C020CBSMsg.IDO_DIV, "00019");
		// 割引解約キャンセル契機コード
// OM-2014-0000350 2014.04.15 Y.Kanata MOD START
//		condiMap.put( EKK0451C020CBSMsg.WRIB_DSL_CNCL_OPTY_CD, "1");
		condiMap.put( EKK0451C020CBSMsg.WRIB_DSL_CNCL_OPTY_CD, "2");
// OM-2014-0000350 2014.04.15 Y.Kanata MOD END
		// 更新年月日時分秒(更新前)
		condiMap.put( EKK0451C020CBSMsg.UPD_DTM_BF, updDtm);
		// サービス課金開始年月日
		condiMap.put( EKK0451C020CBSMsg.SVC_CHRG_STAYMD, svcChrgStaYmd);
		// サービス課金終了年月日算出フラグ
// OM-2014-0000350 2014.04.15 Y.Kanata MOD START
//		condiMap.put( EKK0451C020CBSMsg.SVC_CHRG_ENDYMD_FLG, "0");
		condiMap.put( EKK0451C020CBSMsg.SVC_CHRG_ENDYMD_FLG, "1");
// OM-2014-0000350 2014.04.15 Y.Kanata MOD END
		
		reqMap = mapper.setEKK0451C020_2( param, fixedText, condiMap, "1" );
		resMap = scCall.run( reqMap, keepSesHandle.get() );
		HashMap<String, Object> c020Map = mapper.getEKK0451C020_2( param, fixedText, resMap );
		mapper.scResultCheck( param );
		if (c020Map == null) {
			return param;
		}
		updDtm = (String)c020Map.get(EKK0451C020CBSMsg.UPD_DTM);
		String dslGeneAddDtm = (String)c020Map.get(EKK0451C020CBSMsg.GENE_ADD_DTM);
		String chrgEndYmdOut = (String)c020Map.get(EKK0451C020CBSMsg.SVC_CHRG_ENDYMD_O);
		
		// 割引サービス解約確定
		condiMap.clear();
		// 割引サービス契約番号
		condiMap.put( EKK0451C030CBSMsg.WRIB_SVC_KEI_NO, wriSvcKeiNo);
		// 世代登録年月日時分秒
		condiMap.put( EKK0451C030CBSMsg.GENE_ADD_DTM, dslGeneAddDtm);
		// サービス終了年月日
		condiMap.put( EKK0451C030CBSMsg.SVC_ENDYMD, opeDate);
		// サービス課金終了年月日
		condiMap.put( EKK0451C030CBSMsg.SVC_CHRG_ENDYMD, chrgEndYmdOut);
		// サービス解約年月日
		condiMap.put( EKK0451C030CBSMsg.SVC_DSL_YMD, opeDate);
		// サービス解約理由コード
		condiMap.put( EKK0451C030CBSMsg.SVC_DLRE_CD, "01");
		// 更新年月日時分秒(更新前)
		condiMap.put( EKK0451C030CBSMsg.UPD_DTM_BF, updDtm);
		
		reqMap = mapper.setEKK0451C030( param, fixedText, condiMap, "1" );
		resMap = scCall.run( reqMap, keepSesHandle.get() );
		mapper.getEKK0451C030( param, fixedText, resMap );
		mapper.scResultCheck( param );
		
		return param;
	}
	
	public static String addYYYYMMDD(String trgtYmd, int addDay) throws Throwable
	{
		// 年月日が空の場合
		if (trgtYmd == null || "".equals(trgtYmd))
		{
			return trgtYmd;
		}

		// 年月日が８桁に満たない場合
		if (trgtYmd.length() < 8)
		{
			return trgtYmd;
		}

		// 年月日の抽出
		int year  = Integer.parseInt(trgtYmd.substring(0, 4));
		int month = Integer.parseInt(trgtYmd.substring(4, 6));
		int day   = Integer.parseInt(trgtYmd.substring(6, 8));

		Calendar cal = Calendar.getInstance();
		cal.set(year, month - 1, day);
		// 日付を算出
		cal.add(Calendar.DATE, addDay);

		return String.format("%tY%tm%td", cal, cal, cal);
	}
// OM-2014-0000350 2014.04.11 Y.Kanata ADD END

}