/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKPrgAddCC
*	ソースファイル名：JKKPrgAddCC.java
*	作成者			：FJ
*	日付			：2011年12月12日
*＜機能概要＞ 
*	契約紐付変更登録の共通コンポーネント
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/12/12	FJ			新規作成
*	v4.00.00	2012/08/20  FJ）中井	【ANK-0035-00-00】対応
*	v4.00.01	2012/12/28  FJ）稲岡	【IT1-2012-0002611】対応
*	v4.00.02	2013/03/02	FJ）宇野	【OT-2013-0000292】対応
*	v4.00.03	2013/05/30	FJ）宇野	【IT1-2013-0001246】対応
*	v8.00.00	2014/02/14	FJ）稲岡	【ST-2014-0000048】対応
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;

import eo.common.constant.JKKStrConst;
import eo.ejb.cbs.cbsmsg.EKK1091D010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK1091D010CBSMsg1List;

/**
 * 
 * @author 909486
 *
 */
public class JKKPrgAddCC extends AbstractCommonComponent
{
	/**
	 * テンプレートID
	 */
	private static final String TEMPLATE_ID = "EKK1091D010";
	
	/**
	 * 進捗登録（契約者併合登録完了・請求先併合完了）を行います。
	 * 
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return IRequestParameterReadWrite
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite addPrg(SessionHandle handle, 
												IRequestParameterReadWrite param, 
												String fixedText) throws Exception
	{
		// ユーザデータ情報
		HashMap<String, Object> dataMap = (HashMap<String, Object>)param.getData(fixedText);
		
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		Map<?, ?> result = null;
		IRequestParameterReadWrite retParam = param;
		HashMap<String, Object> paramMap = null;
		HashMap<String, String> svcMap = null;
		
		// 変更対象のリストを取得
		HashMap<String, Object> work01Map = (HashMap<String, Object>)param.getData("KKSV0360WORK01");
		ArrayList list = (ArrayList)work01Map.get("svc_kei_list");
		
		/* ++++++++++ v4.00.01 追加開始 ++++++++++ */
		// 異動区分（お客様併合）
		String idoDivCustHg = (String)dataMap.get("ido_div");
		// 進捗ステータス（契約者併合登録完了）
		String prgStatCustHg = (String)dataMap.get("prg_stat");
		
		// 異動区分（請求契約併合）
		String idoDivSeikyHg = "";
		// 進捗ステータス（請求先併合完了）
		String prgStatSeikyHg = "";
		/* ++++++++++ v4.00.01 追加終了 ++++++++++ */
		
		/* ++++++++++ v4.00.02 追加開始 ++++++++++ */
		String prgtkjk = "";
		/* ++++++++++ v4.00.02 追加終了 ++++++++++ */
		
		// 請求先同時併合
		boolean seikyDojiheigoFlg = false;
		if("ON".equals((String)work01Map.get("seiky_doji_heigo")))
		{
			seikyDojiheigoFlg = true;
			idoDivSeikyHg = (String)dataMap.get("ido_div_seiky_hg");
			prgStatSeikyHg = (String)dataMap.get("prg_stat_seiky_hg");
		}
		
		// 併合先請求契約番号
		String skSeikyKeiNo = (String)work01Map.get("sk_seiky_kei_no");
		
		// 申込明細番号
		Map<Object, Object> workMap = (Map<Object, Object>)param.getMappingWorkArea();
		HashMap workDataMap = (HashMap)workMap.get("WORK");
		String mskmDtlNo = (String)workDataMap.get("mskm_dtl_no");
		
		for(int i=0; i<list.size(); i++)
		{
			svcMap = (HashMap)list.get(i);
			
			// 画面で選択されている場合
			if((Boolean.valueOf(svcMap.get("isSelect"))))
			{
				/* ++++++++++ v4.00.01 修正開始 ++++++++++ */
				// ************************************************************
				// 進捗：契約者併合完了
				// 請求契約番号は格納しない
				// ************************************************************
				/* ++++++++++ v4.00.02 追加開始 ++++++++++ */
				paramMap = editInMsg(param, dataMap, svcMap, mskmDtlNo, "", idoDivCustHg, prgStatCustHg, "");
				/* ++++++++++ v4.00.02 追加終了 ++++++++++ */
				result = scCall.run(paramMap, handle);
				retParam = editOutMsg(result, param, dataMap, fixedText, svcMap);
				
				// リターンコード判定
				if(0 != (Integer)(result.get(JCMConstants.RET_CD_INT_KEY)))
				{
					return retParam;
				}
				
				// 請求先同時併合
				if(seikyDojiheigoFlg)
				{
					// ************************************************************
					// 進捗：請求先併合完了
					// 併合先
					// ************************************************************
					/* ++++++++++ v4.00.02 追加開始 ++++++++++ */
					prgtkjk = "併合後請求先番号：" + skSeikyKeiNo;
					paramMap = editInMsg(param, dataMap, svcMap, mskmDtlNo, skSeikyKeiNo, idoDivSeikyHg, prgStatSeikyHg, prgtkjk);
					/* ++++++++++ v4.00.02 追加終了 ++++++++++ */
					
					result = scCall.run(paramMap, handle);
					retParam = editOutMsg(result, param, dataMap, fixedText, svcMap);
					
					// リターンコード判定
					if(0 != (Integer)(result.get(JCMConstants.RET_CD_INT_KEY)))
					{
						return retParam;
					}
					
					// ************************************************************
					// 進捗：請求先併合完了
					// 併合元
					// ************************************************************
					/* ++++++++++ v4.00.02 追加開始 ++++++++++ */
					prgtkjk = "併合前請求先番号：" + (String)svcMap.get("seiky_kei_no");
					paramMap = editInMsg(param, dataMap, svcMap, mskmDtlNo, svcMap.get("seiky_kei_no"), idoDivSeikyHg, prgStatSeikyHg, prgtkjk);
					/* ++++++++++ v4.00.02 追加終了 ++++++++++ */
					
					result = scCall.run(paramMap, handle);
					retParam = editOutMsg(result, param, dataMap, fixedText, svcMap);
					
					// リターンコード判定
					if(0 != (Integer)(result.get(JCMConstants.RET_CD_INT_KEY)))
					{
						return retParam;
					}
				}
				/* ++++++++++ v4.00.01 修正終了 ++++++++++ */
			}
		}
		
		return retParam;
	}
	
	/**
	 * チェック処理です。<br>
	 * <br>
	 * 
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	public HashMap getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
			throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		List<CAANMsg> templates = new ArrayList<CAANMsg>();
		
		// チェック用サービスインターフェイス
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, Arrays.asList(templates));
		
		return paramMap;
	}
	
	/**
	 * 進捗登録用のメッセージを作成します。
	 * 
	 * @param param
	 * @param inMap
	 * @param svcMap
	 * @param mskmDtlNo
	 * @param seikyKeiNo
	 * @param idoDiv
	 * @param prgStat
	 * @param prg_tkjk
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException
	 */
	private HashMap<String, Object> editInMsg(IRequestParameterReadWrite param,
												HashMap<String, Object> inMap,
												HashMap<String, String> svcMap,
												String mskmDtlNo, 
												String seikyKeiNo, 
												String idoDiv, 
												String prgStat,
												String prg_tkjk) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文ID
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		paramMap.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		paramMap.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());
		
		// 【取得元：ユーザエリア(コントロールマップ)】
		// 依頼先ホスト名
		paramMap.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		
		CAANMsg template = new CAANMsg(EKK1091D010CBSMsg.class.getName());
		
		// テンプレートID
		template.set(EKK1091D010CBSMsg.TEMPLATEID, TEMPLATE_ID);
		
		template.set(EKK1091D010CBSMsg.FUNC_CODE, "1");
		
		// オペレータID
		Object operatorId = param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);
		
		// 運用日付
		Object operateDate = param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);
		
		// 運用日時
		Object operateDateTime = param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);
		
		// ◇ 業務データの設定
		template.set(EKK1091D010CBSMsg.MSKM_DTL_NO, mskmDtlNo);								// 申込明細番号
		template.set(EKK1091D010CBSMsg.SEIKY_KEI_NO, seikyKeiNo);							// 請求契約番号
		/* ++++++++++ v4.00.01 修正開始 ++++++++++ */
		template.set(EKK1091D010CBSMsg.IDO_DIV, idoDiv);									// 異動区分
		template.set(EKK1091D010CBSMsg.PRG_STAT, prgStat);									// 進捗ステータス
		/* ++++++++++ v4.00.01 修正終了 ++++++++++ */
		setParam(template, svcMap, EKK1091D010CBSMsg.SVC_KEI_NO, "svc_kei_no");				// サービス契約番号
		setParam(template, inMap, EKK1091D010CBSMsg.IDO_DTM, "ido_dtm");					// 異動年月日時分秒
		
		/* ++++++++++ v4.00.02 修正開始 ++++++++++ */
		template.set(EKK1091D010CBSMsg.PRG_TKJK_1, prg_tkjk);								// 特記事項１
		/* ++++++++++ v4.00.02 修正終了 ++++++++++ */
		
		CAANMsg childTemplate = new CAANMsg(EKK1091D010CBSMsg1List.class.getName());
		setParam(childTemplate, inMap, EKK1091D010CBSMsg1List.IDO_RSN_CD, "ido_rsn_cd");	// 異動理由コード
		childTemplate.setNull(EKK1091D010CBSMsg1List.IDO_RSN_MEMO);							// 異動理由メモ
		CAANMsg[] childTemplates = new CAANMsg[1];
		childTemplates[0] = childTemplate;
		template.set(EKK1091D010CBSMsg.EKK1091D010CBSMSG1LIST, childTemplates);
		
		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);
		
		return paramMap;
	}
	
	/**
	 * 
	 * @param msgList
	 * @param param
	 * @param dataMap
	 * @param fixedText
	 * 
	 * @return IRequestParameterReadWrite
	 * 
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editOutMsg(Map<?, ?> msgList,
													IRequestParameterReadWrite param,
													HashMap<String, Object> dataMap,
													String fixedText,
													HashMap<String, String> svcMap) throws Exception
	
	{
		// SCからの戻り値からCAANMsgを取得する
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg parentTemplate = templates[0];
		
		// 作業領域の取得
		Map workMap = (Map)param.getMappingWorkArea();
		if (workMap == null) {
			workMap = new HashMap();
			param.setMappingWorkArea(workMap);
		}
		
/* ++++++++++ v4.00.00 追加開始 ++++++++++ */
		HashMap<String, Object> workDataMap = (HashMap<String, Object>)workMap.get("WORK");
		if (workDataMap == null) {
			workDataMap = new HashMap();
			workMap.put("WORK", workDataMap);
		}
		ArrayList<HashMap<String, Object>> prgDtmMapList = (ArrayList<HashMap<String, Object>>)workMap.get("prgDtmMapList");
		if (prgDtmMapList == null) {
			prgDtmMapList = new ArrayList<HashMap<String, Object>>();
			workMap.put("prgDtmMapList", prgDtmMapList);
		}
		
/* ++++++++++ v8.00.00 追加開始 ++++++++++ */
		// サービスが"51":ｍｉｎｅｏ以外の場合
		if(!JKKStrConst.CD00130_51.equals((String)svcMap.get("svc_cd_KK0081")))
		{
			//料金グループコードネット("02","03","04")の場合にのみ設定
			String prcGrpCd = svcMap.get("prc_grp_cd_KK0081");
			// 進捗登録マップ.進捗年月日時分秒 ← 進捗年月日時分秒
			if (!parentTemplate.isNull(EKK1091D010CBSMsg.PRG_DTM)
					&&("02".equals(prcGrpCd) || "03".equals(prcGrpCd) || "04".equals(prcGrpCd))) {
				HashMap<String, Object> prgDtmMap = new HashMap<String, Object>();
				
				prgDtmMap.put("prg_dtm",  parentTemplate.getString(EKK1091D010CBSMsg.PRG_DTM));
				prgDtmMap.put("svc_kei_no",  parentTemplate.getString(EKK1091D010CBSMsg.SVC_KEI_NO));
				prgDtmMapList.add(prgDtmMap);
			}
		}
/* ++++++++++ v8.00.00 追加開始 ++++++++++ */
/* ++++++++++ v4.00.00 追加終了 ++++++++++ */
		
		// 進捗登録マップ.進捗番号 ← 進捗番号
		if (parentTemplate.isNull(EKK1091D010CBSMsg.PRG_NO)) 
		{
			svcMap.put("prg_no", "");
		}
		else 
		{
			svcMap.put("prg_no", parentTemplate.getString(EKK1091D010CBSMsg.PRG_NO));
		}
		
		/* ◇処理結果の判定*/
		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		// リターンコード取得
		String rtnCode = msgList.get(JCMConstants.RET_CD_INT_KEY).toString();
		Integer status = parentTemplate.getInt(JCMConstants.STATUS_INT_KEY);
		
		// エラー情報の設定
		IRequestParameterReadWrite retParam = this.editErrorInfo(param, templates, Integer.parseInt(rtnCode), fixedText);
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)retParam.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if (errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		retParam.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(msgList, errList));
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(rtnCode) && 0 == status)){
			SCCallException scCallEx = new SCCallException("戻り値不正", rtnCode, status);
			throw scCallEx;
		}
		
		return retParam;
	}
	
	/**
	 * 
	 * @param param
	 * @param templates
	 * @param returnCode
	 * @param fixedText
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param, 
														CAANMsg[] templates,
														int returnCode,
														String fixedText) throws RequestParameterException
	{
		CAANMsg template = templates[0];
		
		int templateStatus = template.getInt(EKK1091D010CBSMsg.STATUS);
		if (returnCode != 0)
		{
			templateStatus = 9000;
		}
		
		if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", templateStatus)) == null)
		{
			templateStatus = 0;
		}
		
		int bpStatus = 0;
		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		if (obj == null)
		{
			bpStatus = -1;
		}
		else
		{
			bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
		}
		
		if (templateStatus > bpStatus)
		{
			// BPにサービスコンポーネントのステータスを設定する。
			String formatStatus = String.format("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}
		
		// ユーザデータ情報
		HashMap<String, Object> inMap = (HashMap<String, Object>)param.getData(fixedText);
		
		// エラー情報の設定
		setErr(template, inMap, EKK1091D010CBSMsg.SVC_KEI_NO_ERR, "svc_kei_no_err");	// サービス契約番号
		setErr(template, inMap, EKK1091D010CBSMsg.IDO_DIV_ERR, "ido_div_err");			// 異動区分
		setErr(template, inMap, EKK1091D010CBSMsg.PRG_STAT_ERR, "prg_stat_err");		// 進捗ステータス
		setErr(template, inMap, EKK1091D010CBSMsg.IDO_DTM_ERR, "ido_dtm_err");			// 異動年月日時分秒
		setErr(template, inMap, EKK1091D010CBSMsg.SEIKY_KEI_NO_ERR, "seiky_kei_no_err");// 請求契約番号
		
		// 異動理由明細の取得
		CAANMsg[] templateArray = template.getCAANMsgList(EKK1091D010CBSMsg.EKK1091D010CBSMSG1LIST);
		ArrayList<HashMap<String, Object>> dataList = (ArrayList<HashMap<String, Object>>)inMap.get("EKK1091D010CBSMsg1List");
		
		if(!isNull(dataList) && dataList.size() > 0)
		{
			HashMap<String, Object> childMap = dataList.get(0);
			setErr(templateArray[0], childMap, EKK1091D010CBSMsg1List.IDO_RSN_CD, "ido_rsn_cd_err");	// 異動理由
		}
		
		return param;
	}
	
	/**
	 * パラメータを設定します。
	 * @param template
	 * @param map
	 * @param item
	 * @param key
	 * @return 判定結果
	 */
	@SuppressWarnings("unchecked")
	private void setParam(CAANMsg template, HashMap map, String item, String key)
	{
		String value = null;
		
		if(isNull(map))
		{
			template.setNull(item);
		}
		else
		{
			value = (String)map.get(key);
			if(isEmpty(value))
			{
				template.setNull(item);
			}
			else
			{
				template.set(item, value);
			}
		}
	}
	
	/**
	 * エラー情報を設定します。
	 * @param template
	 * @param map
	 * @param item
	 * @param key
	 * @return 判定結果
	 */
	private void setErr(CAANMsg template, HashMap<String, Object> inMap, String item, String key) {
		
		if (!template.isNull(item))
		{
			if (!inMap.containsKey(key))
			{
				inMap.put(key, template.getString(item));
			}
		}
	}
	
	/**
	 * 引数のNULL判定を行います。
	 * @param param
	 * @return 判定結果
	 */
	private boolean isNull(Object param)
	{
		if(param == null)
		{
			return true;
		}
		return false;
	}
	
	/**
	 * 引数の空文字判定を行います。
	 * @param param
	 * @return 判定結果
	 */
	private boolean isEmpty(String param)
	{
		if(param == null || "".equals(param))
		{
			return true;
		}
		return false;
	}
	
}
