/********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************
 *＜プログラム内容＞
 *  システム名      ：eo顧客基幹システム
 *  モジュール名    ：JKKAdchgHimozukeKojiakNoGetterCC
 *  ソースファイル名：JKKAdchgHimozukeKojiakNoGetterCC.java
 *  作成者          ：FJ
 *  日付            ：2015年10月19日
 *＜機能概要＞
 *  住所変更紐付け対象工事案件番号取得ＣＣ部品
 *＜修正履歴＞
 *  バージョン  修正日      修正者      修正内容
 *  v20.00.00   2015/10/19  FJ)星野     新規作成（【ANK-2643-00-00】 住変時のVA解約処理の見直し対応）
 *
 ********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKAdchgConstCC;
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.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.sun.enterprise.tools.common.util.StringUtils;

import eo.common.constant.JKKStrConst;
import eo.ejb.cbs.cbsmsg.EKK2091B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK2101B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0011A010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0081B010CBSMsg1List;

public class JKKAdchgHimozukeKojiakNoGetterCC  extends AbstractCommonComponent {
	
	/** サービスインタフェース呼び出しで使用するマッパー群 */
	private JKKAdchgMapperCC mapper = null;
	
	/** SC呼び出し部品 */
	private ServiceComponentRequestInvoker scCall = null;
	
	
	/** 紐付け対象工事案件番号（ネット/電話） */
	public static final String HIMOZUKE_KOJIAK_NO_NET_TEL = "himozukeKojiakNoNetTel";
	/** 紐付け対象工事案件番号（テレビ） */
	public static final String HIMOZUKE_KOJIAK_NO_TV = "himozukeKojiakNoTv";
	
	
	/**
	 * コンストラクタ
	 */
	public JKKAdchgHimozukeKojiakNoGetterCC(){
	}
	
	/**
	 * 初期化処理
	 * 
	 * <br>
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return void
	 * @throws Throwable 
	 */
	private void init(IRequestParameterReadWrite param, String fixedText)
	throws Throwable
	{
		// マッパーの初期化
		if (null == this.mapper)
		{
			this.mapper = new JKKAdchgMapperCC();
		}
		
		// SC呼び出し部品のインスタンス生成
		if (null == this.scCall)
		{
			this.scCall = new ServiceComponentRequestInvoker();
		}
		
	}

	/**
	 * 住所変更紐付け対象工事案件番号取得処理
	 * <br>
	 * @param   handle     セッションマネージャなどを持ったハンドル情報
	 * @param   param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param   fixedText  ユーザ任意文字列
	 * @throws  Throwable  例外が発生した場合
	 * @return  リクエストパラメータ(param)に戻り値を追加して返却する
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite execute(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable {
		
		// 初期処理
		init(param, fixedText);
		
		// 処理に必要な情報をパラメータより取得
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		if (paramMap == null || paramMap.isEmpty()) {
			return param;
		}
		
		// 紐付け対象工事案件番号（ネット/電話）
		String himozukeKojiakNoNetTel = "";
		// 紐付け対象工事案件番号（テレビ）
		String himozukeKojiakNoTv = "";
		
		// 工事依頼方法
		String kojiIraiWay = (String)paramMap.get("kojiIraiWay");
		// 依頼工事
		String kojiIraiCd = (String)paramMap.get("kojiIraiCd");
		// 移転元サービス契約回線内訳番号
		String itnmSvkeiKisuwNo = (String)paramMap.get("itnmSvkeiKisuwNo");
		// 移転元サービス契約番号（ネット）
		String svcKeiNoNet = (String)paramMap.get("svcKeiNoNet");
		// 移転元サービス契約番号（電話）
		String svcKeiNoTel = (String)paramMap.get("svcKeiNoTel");
		// 移転元サービス契約番号（テレビ）
		String svcKeiNoTv = (String)paramMap.get("svcKeiNoTv");
		
		// ネット変更区分
		HashMap<String, Object> KKSV0674005CCMap = (HashMap<String, Object>)param.getData("KKSV0674005CC");
		String jdgChgDivNet = (String)KKSV0674005CCMap.get("jdg_chg_div_net");
		// 電話変更区分
		HashMap<String, Object> KKSV0674036CCMap = (HashMap<String, Object>)param.getData("KKSV0674036CC");
		String jdgChgDivTel = (String)KKSV0674036CCMap.get("jdg_chg_div_tel");
		// テレビ変更区分
		HashMap<String, Object> KKSV0674048CCMap = (HashMap<String, Object>)param.getData("KKSV0674048CC");
		String jdgChgDivTv = (String)KKSV0674048CCMap.get("jdg_chg_div_tv");
		
		
		
		// ネット/電話工事紐付け要否
		boolean isNetTelHimozuke = true;
		// テレビ工事紐付け要否
		boolean isTvHimozuke = true;
		
		// 撤去工事依頼がある場合は新たな撤去工事が立ち上がるので紐付け不要と判断し処理対象外
		// 工事依頼方法が「同時」 または 
		// 工事依頼方法が「個別」 かつ 依頼工事が「撤去」
		if( JKKAdchgConstCC.CD01554_DOJI.equals(kojiIraiWay) 
			|| ( JKKAdchgConstCC.CD01554_KOBETU.equals(kojiIraiWay) && JKKAdchgConstCC.CD01555_TEKKYO.equals(kojiIraiCd))
		){
			// 処理対象外
			return param;
		}
		
		// ネット/電話が引越しでない場合
		if( !isHikkoshi(jdgChgDivNet) && !isHikkoshi(jdgChgDivTel) ){
			// ネット/電話工事の紐付けは不要
			isNetTelHimozuke = false;
		}
		
		// テレビが引越しでない場合
		if( !isHikkoshi(jdgChgDivTv) ){
			// テレビ工事の紐付けは不要
			isTvHimozuke = false;
		}
		
		// 両方紐付け不要なら処理対象外
		if(!isNetTelHimozuke && !isTvHimozuke){
			return param;
		}
		
		
		
		// ・EKK2091B001 住所変更一覧照会
		// 機能コード：2で論理削除済みのレコードを取得
		HashMap<String, Object> kk2091_b001_map = 
			getEKK2091B001_2Map( handle, param, fixedText, itnmSvkeiKisuwNo );
		// 該当レコードなしの場合、処理対象外
		if(kk2091_b001_map==null){
			return param;
		}
		
		// 住所変更番号を取得
		String adchgNo = (String)kk2091_b001_map.get(EKK2091B001CBSMsg1List.ADCHG_NO);
		
		
		
		// ・EKK2101B001 住所変更明細一覧照会 住所変更明細種別コード=06:工事案件
		// 機能コード：2で論理削除済みのレコードを取得
		ArrayList<HashMap<String, Object>> kk2101_b001_list = 
			getEKK2101B001_2Map( handle, param, fixedText, adchgNo );
		// 該当レコードなしの場合、処理対象外
		if(kk2101_b001_list==null || kk2101_b001_list.isEmpty()){
			return param;
		}

		// 住所変更明細（最大2件）の件数分ループ
		for(HashMap<String, Object> kk2101_b001_map : kk2101_b001_list){
			
			// 変更前識別番号（=撤去工事案件番号）
			String chbfSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHBF_SKBT_NO);
			// 変更後識別番号（=新設工事案件番号）
			String chafSkbtNo = (String)kk2101_b001_map.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO);
			
			
			// 変更前識別番号（=撤去工事案件番号）が未設定の場合、処理対象外
			if(StringUtils.isEmpty(chbfSkbtNo)){
				// 次の住所変更明細を処理する
				continue;
			}
			
			// 撤去工事の工事案件を取得
			HashMap<String, Object>ku0011_a010_map_tekkyo = getEKU0011A010(handle, param, fixedText, chbfSkbtNo);
			// 該当レコードなしの場合、処理対象外
			if(ku0011_a010_map_tekkyo==null || ku0011_a010_map_tekkyo.isEmpty()){
				// 次の住所変更明細を処理する
				continue;
			}
			// 撤去工事が完了済でない場合、処理対象外
			if( !isKojiFinZm(ku0011_a010_map_tekkyo) ){
				// 次の住所変更明細を処理する
				continue;
			}
			
			// ・EKU0081B010  サービス契約＿工事案件一覧照会
			List<HashMap<String, Object>> ku0081_b010_list_tekkyo = getEKU0081B010(handle, param, fixedText, chbfSkbtNo);
			// 該当レコードなしの場合、処理対象外
			if(ku0081_b010_list_tekkyo==null || ku0081_b010_list_tekkyo.isEmpty()){
				// 次の住所変更明細を処理する
				continue;
			}
			
			// 工事案件に紐づくサービス契約番号をリストアップする
			List<String> kojiakSvcKeiNoList = getKojiakSvcKeiNoList(ku0081_b010_list_tekkyo);
			
			// サービス契約＿工事案件のサービスコードを元に、ネット/電話工事 と テレビ工事 を切り分け
			boolean isNetTelKoji = isNetTelKoji(ku0081_b010_list_tekkyo);
			// ネット/電話工事の場合
			if(isNetTelKoji){
				
				// ネットサービス契約番号のチェック
				if(!StringUtils.isEmpty(svcKeiNoNet) && !kojiakSvcKeiNoList.contains(svcKeiNoNet)){
					// 次の住所変更明細を処理する
					continue;
				}
				
				// 電話サービス契約番号のチェック
				if(!StringUtils.isEmpty(svcKeiNoTel) && !kojiakSvcKeiNoList.contains(svcKeiNoTel)){
					// 次の住所変更明細を処理する
					continue;
				}
				
			// テレビ工事の場合
			}else{
				
				// テレビサービス契約番号のチェック
				if(!StringUtils.isEmpty(svcKeiNoTv) && !kojiakSvcKeiNoList.contains(svcKeiNoTv)){
					// 次の住所変更明細を処理する
					continue;
				}
			}
			
			
			
			// 変更後識別番号（=新設工事案件番号）が設定ありの場合、新設工事のステータスチェック
			if(!StringUtils.isEmpty(chafSkbtNo)){
				
				// 新設工事の工事案件を取得
				HashMap<String, Object>ku0011_a010_map_sinsetu = getEKU0011A010(handle, param, fixedText, chafSkbtNo);
				// 該当レコードなしの場合、処理対象外
				if(ku0011_a010_map_sinsetu==null || ku0011_a010_map_sinsetu.isEmpty()){
					// 次の住所変更明細を処理する
					continue;
				}
				// 新設工事が中止でない場合、処理対象外
				if( !isKojiCancel(ku0011_a010_map_sinsetu) ){
					// 次の住所変更明細を処理する
					continue;
				}

			}
			
			// ここまで来たら紐付け対象
			// ネット/電話工事の場合
			if(isNetTelKoji){
				
				// ネット/電話の紐付け要否判定
				if(isNetTelHimozuke){
					// 撤去工事案件番号を紐付け対象（ネット/電話）とする
					himozukeKojiakNoNetTel = chbfSkbtNo;
				}
				
			// テレビ工事の場合
			}else{
				
				// テレビの紐付け要否判定
				if(isTvHimozuke){
					// 撤去工事案件番号を紐付け対象（テレビ）とする
					himozukeKojiakNoTv = chbfSkbtNo;
				}
			}
		}

		// 紐付け対象工事案件番号（ネット/電話）
		paramMap.put(HIMOZUKE_KOJIAK_NO_NET_TEL, himozukeKojiakNoNetTel);
		// 紐付け対象工事案件番号（テレビ）
		paramMap.put(HIMOZUKE_KOJIAK_NO_TV, himozukeKojiakNoTv);

		return param;
	}

	/**
	 * 引越し（解約/新規除く）判定
	 * @param jdgChgDiv 変更区分
	 * @return 入力の変更区分が引越しの場合true, 以外はfalse
	 */
	private boolean isHikkoshi(String jdgChgDiv) {
		// 変更区分が継続・変更の場合true （解約/新規はfalse返却）
		return JKKAdchgConstCC.AD_CHG_CMT_KEEP_STR.equals(jdgChgDiv) || JKKAdchgConstCC.AD_CHG_CMT_MODIFY_STR.equals(jdgChgDiv);
	}

	/**
	 * 工事完了済判定
	 * @param ku0011_a010_map 工事案件一意照会マップ
	 * @return 工事完了済の場合true, 以外はfalse
	 */
	private boolean isKojiFinZm(HashMap<String, Object>ku0011_a010_map) {
		
		// 工事案件ステータス
		String kojiakStat = (String)ku0011_a010_map.get(EKU0011A010CBSMsg1List.KOJIAK_STAT);
		// マンション工事案件ステータス
		String mansKojiakStat = (String)ku0011_a010_map.get(EKU0011A010CBSMsg1List.MANS_KOJIAK_STAT_CD);
		
		// 工事案件ステータス＝「200（工事完了済）」
		// または 工事案件ステータス＝「120（登録済）」 かつ マンション工事案件ステータス＝「200（工事完了済）」
		return JKKStrConst.CD00474_KJ_FIN_ZM.equals(kojiakStat) 
				|| ( JKKStrConst.CD00474_120.equals(kojiakStat) && JKKStrConst.CD00474_KJ_FIN_ZM.equals(mansKojiakStat) );
	}
	
	/**
	 * 工事中止済判定
	 * @param ku0011_a010_map 工事案件一意照会マップ
	 * @return 工事中止済の場合true, 以外はfalse
	 */
	private boolean isKojiCancel(HashMap<String, Object>ku0011_a010_map) {
		
		// 工事案件ステータス
		String kojiakStat = (String)ku0011_a010_map.get(EKU0011A010CBSMsg1List.KOJIAK_STAT);
		// マンション工事案件ステータス
		String mansKojiakStat = (String)ku0011_a010_map.get(EKU0011A010CBSMsg1List.MANS_KOJIAK_STAT_CD);
		
		// 工事案件ステータス＝「900（中止）」
		// または 工事案件ステータス＝「120（登録済）」 かつ マンション工事案件ステータス＝「900（中止）」
		return JKKStrConst.CD00474_900.equals(kojiakStat) 
				|| ( JKKStrConst.CD00474_120.equals(kojiakStat) && JKKStrConst.CD00474_900.equals(mansKojiakStat) );
	}
	
	/**
	 * ネット/電話工事判定
	 * @param ku0081_b010_list サービス契約＿工事案件一覧照会リスト
	 * @return ネット/電話工事の場合true, 以外はfalse
	 */
	private boolean isNetTelKoji(List<HashMap<String, Object>> ku0081_b010_list) {
		
		// 1件目のサービスコードを元に判定
		HashMap<String, Object> ku0081_b010_map = ku0081_b010_list.get(0);
		
		// サービスコード
		String svcCd = (String)ku0081_b010_map.get(EKU0081B010CBSMsg1List.SVC_CD);
		
		// サービスコードがネット/電話の場合true
		if(JKKSvcConst.SVC_CD_NET.equals(svcCd) || JKKSvcConst.SVC_CD_TEL.equals(svcCd)){
			return true;
			
		// 以外はfalse
		}else{
			return false;
		}
	}

	/**
	 * 工事案件対象サービス契約リスト作成処理
	 * @param ku0081_b010_list サービス契約＿工事案件一覧照会リスト
	 * @return 工事案件に紐づくサービス契約番号のリストを返却する
	 */
	private List<String> getKojiakSvcKeiNoList( List<HashMap<String, Object>> ku0081_b010_list ) {
		
		// 工事案件に紐づくサービス契約番号をリストアップする
		List<String> kojiakSvcKeiNoList = new ArrayList<String>();
		
		// 該当レコードなしの場合、処理対象外
		if(ku0081_b010_list==null || ku0081_b010_list.isEmpty()){
			// 空リスト返却
			return kojiakSvcKeiNoList;
		}
		// サービス契約＿工事案件 の件数分ループ
		for(HashMap<String, Object> ku0081_b010_map : ku0081_b010_list){
			kojiakSvcKeiNoList.add((String)ku0081_b010_map.get(EKU0081B010CBSMsg1List.SVC_KEI_NO));
		}
		return kojiakSvcKeiNoList;
	}

	/**
	 * EKK2091B001 住所変更一覧照会 機能コード：2（キャンセル済レコードを対象とする）
	 * @param handle           セッションマネージャなどを持ったハンドル情報
	 * @param param            モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param fixedText        ユーザ任意文字列
	 * @param itnmSvkeiKisuwNo 移転元サービス契約回線内訳番号
	 * @return 住所変更一覧照会マップ（先頭の1件を返却 該当レコードなしの場合はnull）
	 */
	private HashMap<String, Object> getEKK2091B001_2Map(
		SessionHandle handle, 
		IRequestParameterReadWrite param,
		String fixedText, 
		String itnmSvkeiKisuwNo
	) throws Exception {
		
		// ・EKK2091B001 住所変更一覧照会
		// 機能コード：2で論理削除済みのレコードを取得
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		HashMap<String, String> condMap = new HashMap<String, String>();
		condMap.clear();
		condMap.put( JKKAdchgMapperCC.COND_KEY_SVC_KEI_KAIS_UCWK_NO, itnmSvkeiKisuwNo );
		reqMap = mapper.setEKK2091B001_2( param, fixedText, condMap );
		resMap = scCall.run( reqMap, handle );
		ArrayList<HashMap<String, Object>> kk2091_b001_list = mapper.getEKK2091B001( param, fixedText, resMap );
		mapper.scResultCheck( param );
		
		// 該当レコードなしの場合、処理対象外
		if(kk2091_b001_list==null || kk2091_b001_list.isEmpty()){
			return null;
		}
		
		// 1件目（=直近の住所変更申込）を取得
		HashMap<String, Object> kk2091_b001_map = kk2091_b001_list.get(0);
		
		return kk2091_b001_map;
	}

	/**
	 * EKK2101B001 住所変更明細一覧照会 機能コード：2（論理削除済レコードも対象とする）
	 * @param handle     セッションマネージャなどを持ったハンドル情報
	 * @param param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param fixedText  ユーザ任意文字列
	 * @param adchgNo    住所変更番号
	 * @return 住所変更明細一覧照会リスト
	 */
	private ArrayList<HashMap<String, Object>> getEKK2101B001_2Map(
		SessionHandle handle, 
		IRequestParameterReadWrite param,
		String fixedText, 
		String adchgNo
	) throws Exception 
	{
		
		// ・EKK2101B001 住所変更明細一覧照会
		// 機能コード：2で論理削除済みのレコードを取得
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		HashMap<String, String> condMap = new HashMap<String, String>();
		condMap.clear();
		condMap.put( JKKAdchgMapperCC.COND_KEY_ADCHG_NO, adchgNo );
		condMap.put(JKKAdchgMapperCC.COND_KEY_ADCHG_DTL_SBT_CD, JKKAdchgConstCC.CD01241_KOJI_ANKN_NO);
		reqMap = mapper.setEKK2101B001_2( param, fixedText, condMap );
		resMap = scCall.run( reqMap, handle );
		ArrayList<HashMap<String, Object>> kk2101_b001_list = mapper.getEKK2101B001( param, fixedText, resMap );
		mapper.scResultCheck( param );
		return kk2101_b001_list;
	}

	/**
	 * EKU0011A010 工事案件一意照会
	 * @param handle     セッションマネージャなどを持ったハンドル情報
	 * @param param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param fixedText  ユーザ任意文字列
	 * @param kojiakNo   工事案件番号
	 * @return 工事案件一意照会マップ 該当レコードなしの場合は空マップ
	 */
	private HashMap<String, Object> getEKU0011A010( 
		SessionHandle handle, 
		IRequestParameterReadWrite param, 
		String fixedText, 
		String kojiakNo
	) throws Exception{
		
		// ・EKU0011A010 工事案件一意照会
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		HashMap<String, String> condMap = new HashMap<String, String>();
		condMap.clear();
		condMap.put( JKKAdchgMapperCC.COND_KEY_KOJIAK_NO, kojiakNo);
		reqMap = mapper.setEKU0011A010( param, fixedText, condMap );
		resMap = scCall.run( reqMap, handle );
		HashMap<String, Object> ku0011_a010 = mapper.getEKU0011A010( param, fixedText, resMap );
		mapper.scResultCheck( param );
		return ku0011_a010;
	}

	/**
	 * EKU0081B010  サービス契約＿工事案件一覧照会
	 * @param handle     セッションマネージャなどを持ったハンドル情報
	 * @param param      モデルグループ、コントロールマップを含むリクエストパラメータ
	 * @param fixedText  ユーザ任意文字列
	 * @param kojiakNo   工事案件番号
	 * @return サービス契約＿工事案件一覧照会リスト 該当レコードなしの場合は空リスト
	 */
	private List<HashMap<String, Object>> getEKU0081B010(
		SessionHandle handle,
		IRequestParameterReadWrite param, 
		String fixedText, 
		String kojiakNo
	) throws Exception {
			
		// ・EKU0081B010  サービス契約_工事案件一覧照会
		HashMap<String, String> condMap = new HashMap<String, String>();
		HashMap<String, Object> reqMap;
		Map<?, ?> resMap;
		condMap.put(JKKAdchgMapperCC.COND_KEY_KOJIAK_NO, kojiakNo);
		reqMap = mapper.setEKU0081B010(param, fixedText, condMap);
		resMap = scCall.run( reqMap, handle );
		List<HashMap<String,Object>> ku0081_b010_list = mapper.getEKU0081B010( param, fixedText, resMap );
		mapper.scResultCheck( param );
		return ku0081_b010_list;
	}

}
