/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom, 2011
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKAdchgCancelKkopSvcKeiCC
*   ソースファイル名：JKKAdchgCancelKkopSvcKeiCC.java
*   作成者          ：富士通
*   日付            ：2013年12月17日
*＜機能概要＞
*   住所変更機器オプションサービス契約キャンセルCCクラスです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2013/12/17   FJ）        新規作成
*
**********************************************************************/
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.JKKSvcConst;
import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
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.EKK2101B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2811A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2811C140CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2811C150CBSMsg;

/**
 * 住所変更機器オプションサービス契約キャンセルCCです。<p>
 * <br>
 * @author FJ
 */
public class JKKAdchgCancelKkopSvcKeiCC extends AbstractCommonComponent
{
	/** SC呼び出し部品 */
	ServiceComponentRequestInvoker scCall = null;
	
	/** サービスインタフェース呼び出しで使用するマッパー群 */
	private JKKAdchgMapperCC mapper = null;
	
	// CC用Map
	private HashMap<String, Object> paramMap = null;

	
	/**
	 * 初期処理
	 * 
	 * @param fixedText ユーザ任意文字列
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	private void init(
			IRequestParameterReadWrite param
			, String fixedText
			) throws RequestParameterException
	{
		// SC呼び出し部品のインスタンス生成
		if (this.scCall == null) {
			this.scCall = new ServiceComponentRequestInvoker();
		}
		
		// マッパーのインスタンス生成
		if (null == this.mapper) {
			this.mapper = new JKKAdchgMapperCC();
		}
		
		// CC用Mapのインスタンス作成
		if (null == this.paramMap) {
			paramMap = (HashMap<String, Object>)param.getData(fixedText);
		}
	}

	/**
	 * 住所変更機器オプションサービス契約キャンセル処理です。
	 * 
	 * 住所変更機器オプションサービス契約キャンセル処理を実行します。
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable 
	 */
	public IRequestParameterReadWrite execute(
			SessionHandle handle
			, IRequestParameterReadWrite param
			, String fixedText
			) throws Throwable
	{
		// 初期処理（SC呼び出し部品、マッパー、CC用Map）
		init(param, fixedText);
		
		// CC用Mapがnullの場合処理終了
		if (paramMap == null) {
			return null;
		}
		
		// 住所変更明細から機器オプションサービス契約番号（追加分）取得
		ArrayList<String> candidateKkopSvcKeiNoList = getAddedKkopSvcKeiNoList(handle, param, fixedText);
		
		// 処理対象が無い場合はreturn
		if (candidateKkopSvcKeiNoList == null
				|| candidateKkopSvcKeiNoList.size()==0) {
			return param;
		}
		
		// 追加機器オプションサービス契約番号を元に一意照会し、対象をキャンセルor解約
		getCancelTargetKkop(handle, param, fixedText, candidateKkopSvcKeiNoList);
		
		return param;
	}

	/**
	 * 住所変更明細から機器オプションサービス契約番号（追加分）を取得する
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws Throwable
	 */
	private ArrayList<String> getAddedKkopSvcKeiNoList(
			SessionHandle handle
			, IRequestParameterReadWrite param
			, String fixedText
			) throws Throwable
	{
		/** 事前準備 */
		ArrayList<String> outList = new ArrayList<String>();
		HashMap<String, String> condMap = new HashMap<String, String>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;

		/** 住所変更明細スキーマデータの取得 */
		condMap.clear();
		condMap.put( JKKAdchgMapperCC.COND_KEY_SYSID, (String)paramMap.get("sysid") );
		condMap.put( JKKAdchgMapperCC.COND_KEY_ADCHG_NO, (String)paramMap.get("adchg_no") );
		condMap.put( JKKAdchgMapperCC.COND_KEY_ADCHG_DTL_SBT_CD, "09" );
		reqMap = mapper.setEKK2101B001( param, fixedText, condMap );
		resMap = scCall.run( reqMap, handle );
		ArrayList<HashMap<String, Object>> kk2101_b001_list = mapper.getEKK2101B001( param, fixedText, resMap );
		mapper.scResultCheck( param );
		
		if (kk2101_b001_list == null) {
			return null;
		}
		
		// 追加された機器オプションサービス契約をListに詰めて返却する
		for (HashMap<String, Object> kk2101_b001_map : kk2101_b001_list) {
			String chafSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			String chbfSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
			// 変更後識別番号のみが入力されている場合、追加された機器オプションサービス契約と判断する。
			if (StringUtils.isEmpty(chbfSkbtNo) && !StringUtils.isEmpty(chafSkbtNo)) {
				outList.add(chafSkbtNo);
			}
		}
		
		return outList;
	}
	
	/**
	 * 追加機器オプションサービス契約一意照会してキャンセル／解約関数に渡す
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param candiList 追加機器オプションサービス契約番号のList
	 * @return
	 * @throws Throwable
	 */
	private ArrayList<HashMap<String, Object>> getCancelTargetKkop(
			SessionHandle handle
			, IRequestParameterReadWrite param
			, String fixedText
			, ArrayList<String> candiList
			) throws Throwable
	{
		/** 事前準備 */
		HashMap<String, String> condMap = new HashMap<String, String>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		ArrayList<HashMap<String, Object>> trgtList = new ArrayList<HashMap<String, Object>>();
		
		for (String kkopSvcKeiNo : candiList) {
			condMap.clear();
			condMap.put( JKKAdchgMapperCC.COND_KEY_KKOP_SVC_KEI_NO, kkopSvcKeiNo );
			condMap.put( JKKAdchgMapperCC.COND_KEY_RSV_APLY_YMD, JKKSvcConst.MAX_YMD );
			// 機器オプションサービス契約一意照会（カレント）
			reqMap = mapper.setEKK2811A010( param, fixedText, condMap, "2" );
			resMap = scCall.run( reqMap, handle );
			ArrayList<HashMap<String, Object>> kk2811_a010_list = mapper.getEKK2811A010( param, fixedText, resMap );
			mapper.scResultCheck( param );
			
			// 対象となるステータスである場合のみキャンセル対象として返却
			for(HashMap<String, Object> kkopInfo : kk2811_a010_list) {
				String stat = (String)kkopInfo.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_STAT);
				if (JKKSvcConst.SVC_KEI_STAT_010.equals(stat)
						|| JKKSvcConst.SVC_KEI_STAT_020.equals(stat)
						|| JKKSvcConst.SVC_KEI_STAT_030.equals(stat)) {
					cancelKkopSvcKei(handle, param, fixedText, kkopInfo);
				}
			}
		}
		
		return trgtList;
	}
	
	/**
	 * 機器オプションサービス契約一意照会結果に対し、キャンセル／解約を行う
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @param trgtMap 機器オプションサービス契約一意照会結果
	 * @throws Throwable
	 */
	private void cancelKkopSvcKei(
			SessionHandle handle
			, IRequestParameterReadWrite param
			, String fixedText
			, HashMap<String, Object> trgtMap
			) throws Throwable
	{
		/** 事前準備 */
		HashMap<String, String> condMap = new HashMap<String, String>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		
		String operateDate = JCCBPCommon.getOpeDate(null);
		String stat = (String)trgtMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_STAT);

		if (JKKSvcConst.SVC_KEI_STAT_010.equals(stat)
				|| JKKSvcConst.SVC_KEI_STAT_020.equals(stat)) {
			condMap.clear();
			condMap.put( JKKAdchgMapperCC.COND_KEY_KKOP_SVC_KEI_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
			condMap.put( JKKAdchgMapperCC.COND_KEY_IDO_DIV, (String)trgtMap.get(EKK2811A010CBSMsg1List.IDO_DIV));
			condMap.put( JKKAdchgMapperCC.COND_KEY_MSKM_DTL_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.MSKM_DTL_NO));
			String lastUpdDtm = (String)trgtMap.get(EKK2811A010CBSMsg1List.LAST_UPD_DTM);
			if (StringUtils.isEmpty(lastUpdDtm)) {
				// 一意照会がlastUpdDtmを取得できない場合の保険
				lastUpdDtm = (String)trgtMap.get(EKK2811A010CBSMsg1List.UPD_DTM);
			}
			condMap.put( "upd_dtm_bf", lastUpdDtm);
			// 機器オプションサービス契約キャンセル
			reqMap = mapper.setEKK2811C110( param, fixedText, condMap );
			resMap = scCall.run( reqMap, handle );
			mapper.getEKK2811C110( param, fixedText, resMap );
			mapper.scResultCheck( param );

		} else if (JKKSvcConst.SVC_KEI_STAT_030.equals(stat)) {
			condMap.clear();
			condMap.put( EKK2811C140CBSMsg.KKOP_SVC_KEI_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
			condMap.put( EKK2811C140CBSMsg.IDO_DIV, (String)trgtMap.get(EKK2811A010CBSMsg1List.IDO_DIV));
			condMap.put( EKK2811C140CBSMsg.MSKM_DTL_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.MSKM_DTL_NO));
			condMap.put( EKK2811C140CBSMsg.SVC_ENDYMD, (String) operateDate);
			condMap.put( EKK2811C140CBSMsg.SVC_CHRG_ENDYMD, addYYYYMMDD((String) operateDate, -1));
			String lastUpdDtm = (String)trgtMap.get(EKK2811A010CBSMsg1List.LAST_UPD_DTM);
			if (StringUtils.isEmpty(lastUpdDtm)) {
				// 一意照会がlastUpdDtmを取得できない場合の保険
				lastUpdDtm = (String)trgtMap.get(EKK2811A010CBSMsg1List.UPD_DTM);
			}
			condMap.put( EKK2811C140CBSMsg.UPD_DTM_BF, lastUpdDtm);
			// 機器オプションサービス契約解約
			reqMap = mapper.setEKK2811C140( param, fixedText, condMap );
			resMap = scCall.run( reqMap, handle );
			HashMap<String, Object> kk2811_c140_map = mapper.getEKK2811C140( param, fixedText, resMap );
			mapper.scResultCheck( param );
			if (kk2811_c140_map == null || !kk2811_c140_map.containsKey(EKK2811C140CBSMsg.UPD_DTM)) {
				return;
			}
			lastUpdDtm = (String)kk2811_c140_map.get(EKK2811C140CBSMsg.UPD_DTM);

			condMap.clear();
			condMap.put( EKK2811C150CBSMsg.KKOP_SVC_KEI_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.KKOP_SVC_KEI_NO));
			condMap.put( EKK2811C150CBSMsg.IDO_DIV, (String)trgtMap.get(EKK2811A010CBSMsg1List.IDO_DIV));
			condMap.put( EKK2811C150CBSMsg.MSKM_DTL_NO, (String)trgtMap.get(EKK2811A010CBSMsg1List.MSKM_DTL_NO));
			condMap.put( EKK2811C150CBSMsg.SVC_DLRE_CD, (String)paramMap.get("svc_dlre_cd") );
			condMap.put( EKK2811C150CBSMsg.SVC_ENDYMD, (String) operateDate);
			condMap.put( EKK2811C150CBSMsg.SVC_CHRG_ENDYMD, addYYYYMMDD((String) operateDate, -1));
			condMap.put( EKK2811C150CBSMsg.UPD_DTM_BF, lastUpdDtm);
			// 機器オプションサービス契約解約確定
			reqMap = mapper.setEKK2811C150( param, fixedText, condMap );
			resMap = scCall.run( reqMap, handle );
			mapper.getEKK2811C150( param, fixedText, resMap );
			mapper.scResultCheck( param );

		}
		return;
	}
	
	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);
	}
}
