/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JCHKssaidkCmpNyukinAddCC
*	ソースファイル名：JCHKssaidkCmpNyukinAddCC.java
*	作成者			：FJ）清原
*	日付			：2016年10月04日
*＜機能概要＞
*	決済代行会社リアル入金情報登録の共通コンポーネントクラスです。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   v32.00.00	2017/04/05  FJ)清原		【ANK-2996-00-00】ＳＭＳを利用した即時決済サービスの導入
*   v32.00.01	2017/04/25  FJ)清原		【IT1-2017-0000026】コンビニリアル速報通知年月日、コンビニリアル速報通知時分秒が設定されない
*	v32.00.02	2017/05/11	FJ)西面		【ANK-2996-00-02】ＳＭＳを利用した即時決済サービスの導入
*	v32.00.03	2017/05/17	FJ)清原		【IT1-2017-0000047】単項目チェックエラー時にトランザクションがロールバックされる
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
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.ErrorLevel;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.bpm.parameter.StatusArea;
import com.fujitsu.futurity.bp.x21.bpm.parameter.StatusInfo;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.bp.x21.values.OUTBREAK_AREA;
import com.fujitsu.futurity.common.JCCSuperComExecUtil;
import com.fujitsu.futurity.common.JCCSyslogFormat;
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 com.fujitsu.futurity.model.common.check.DatetimeCheck;
import com.fujitsu.futurity.model.common.check.EmsizeCharCheck;
import com.fujitsu.futurity.model.common.check.HalfCharCheck;
import com.fujitsu.futurity.model.common.check.LengthCheck;

import eo.common.constant.JACStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JACCommonUtil;
import eo.common.util.JCHStringUtil;
import eo.ejb.cbs.cbsmsg.ECH0901D010CBSMsg;


/**
 * 決済代行会社リアル入金情報登録の共通コンポーネントクラスです。
 * <BR>
 * @author FJ
 */
public class JCHKssaidkCmpNyukinAddCC extends AbstractCommonComponent
{

	// ▼▼▼決済代行会社リアル入金情報受信 定数クラス ▼▼▼
	
	/** テンプレートID　決済代行会社リアル入金情報登録 */
	private static final String TEMPLATE_ID_ECH0901D010 = "ECH0901D010";
	
	// ▽▽▽CHIFE522_決済代行会社リアル入金情報受信▽▽▽
	/** バージョン */
	private static final String VERSION = "version";
	
	/** 決済手段区分 */
	private static final String BILL_METHOD = "bill_method";
	
	/** 決済手段名称 */
	private static final String BILL_METHOD_NAME = "bill_method_name";
	
	/** 決済種類コード */
	private static final String KESSAI_ID = "kessai_id";
	
	/** 決済種類名称 */
	private static final String KESSAI_NAME = "kessai_name";
	
	/** 契約コード */
	private static final String SHOP_CD = "shop_cd";
	
	/** 収納企業コード */
	private static final String SYUNO_CO_CD = "syuno_co_cd";
	
	/** 拠点コード */
	private static final String KYOTEN_CD = "kyoten_cd";
	
	/** 請求番号 */
	private static final String SHOPORDER_NO = "shoporder_no";
	
	/** 請求金額 */
	private static final String SEIKYUU_KINGAKU = "seikyuu_kingaku";
	
	/** 決済受付日 */
	private static final String KESSAI_DATE = "kessai_date";
	
	/** 決済受付時分秒 */
	private static final String KESSAI_TIME = "kessai_time";
	
	/** 決済受付番号 */
	private static final String KESSAI_NO = "kessai_no";
	
	/** 支払期限日 */
	private static final String SHIHARAI_DATE = "shiharai_date";
	
	/** 支払期限時分 */
	private static final String SHIHARAI_TIME = "shiharai_time";
	
	/** 入金日 */
	private static final String NYUKIN_DATE = "nyukin_date";
	
	/** 入金時分 */
	private static final String NYUKIN_TIME = "nyukin_time";
	
	/** 入金金額 */
	private static final String NYUKIN_KINGAKU = "nyukin_kingaku";
	
	/** 振込日 */
	private static final String FURIKOMI_DATE = "furikomi_date";
	
	/** 精算期日 */
	private static final String SEISAN_KIJITU = "seisan_kijitu";
	
	/** コンビニコード */
	private static final String CVS_CD = "cvs_cd";
	
	/** 店舗コード */
	private static final String TEMPO_CD = "tempo_cd";
	
	/** 払出番号1 */
	private static final String HARAIDASHI_NO1 = "haraidashi_no1";
	
	/** 払出番号2 */
	private static final String HARAIDASHI_NO2 = "haraidashi_no2";
	
	/** 払出番号3 */
	private static final String HARAIDASHI_NO3 = "haraidashi_no3";
	
	/** 金融機関コード */
	private static final String BANK_CD = "bank_cd";
	
	/** 金融機関名 */
	private static final String BANK_NAME = "bank_name";
	
	/** 店舗コード */
	private static final String BRANCH_CD = "branch_cd";
	
	/** 収納機関番号 */
	private static final String BRANCH_NAME = "branch_name";
	
	/** お客様番号 */
	private static final String CUST_NO = "cust_no";
	
	/** 確認番号 */
	private static final String KAKUNIN_NO = "kakunin_no";
	
	/** チャネル区分 */
	private static final String CHANEL_KBN = "chanel_kbn";
	
	/** 納付金区分 */
	private static final String NOUFUKIN_KBN = "noufukin_kbn";
	
	/** 入力区分 */
	private static final String NYUURYOKU_KBN = "nyuuryoku_kbn";
	
	/** 納付区分 */
	private static final String NOUFU_KBN = "noufu_kbn";
	
	/** 印紙税 */
	private static final String INSHI_TAX = "inshi_tax";
	
	/** 支払方法 */
	private static final String SHIHARAI_METHOD = "shiharai_method";
	
	/** 結果コード */
	private static final String RESCD = "rescd";
	
	/** 結果内容 */
	private static final String RES = "res";
	
	/** 結果コード */
	private static final String STATUS_CD = "status_cd";
	
	// △△△CHIFE522_決済代行会社リアル入金情報受信△△△

	
	/** 日時書式(yyyyMMddHHmmssSSS) */
	private static final String FMT_YMDHMSS = "yyyyMMddHHmmss";

	/** メッセージ区分 */
	private static final String WAR = "WAR";

	/** エラー項目末尾辞 */
	private static final String PREFIX_ERR_ITEM = "_err";
	
	/** 単項目チェック：必須チェックエラー */
	private static final String TMCK_ERR_E1 = "E1";

	/** 単項目チェック：入力文字種チェックエラー */
	private static final String TMCK_ERR_E2 = "E2";

	/** 単項目チェック：入力文字列長チェックエラー */
	private static final String TMCK_ERR_E3 = "E3";

	/** 単項目チェック：項目固有チェックエラー */
	private static final String TMCK_ERR_E4 = "E4";

	/** 外部インターフェイスID **/
	private static final String CHIFE522 = "CHIFE522";
	/** APIメッセージID **/
	private static final String API_MSG_ID_1 = "EKBE660-TW";
	/** APIメッセージID **/
	private static final String API_MSG_ID_2 = "EKBE670-TW";
	/** APIメッセージID **/
	private static final String API_MSG_ID_3 = "EKBE680-TW";
	/** APIメッセージID **/
	private static final String API_MSG_ID_4 = "EKBE690-TW";
	
	/** 決済代行会社入金情報_出力順 */
	private static final String[] KSDKCP_NKIF_OPUT_JUN = 
	{ VERSION,
			BILL_METHOD, BILL_METHOD_NAME, KESSAI_ID, KESSAI_NAME, SHOP_CD,
			SYUNO_CO_CD, KYOTEN_CD, SHOPORDER_NO, SEIKYUU_KINGAKU, KESSAI_DATE,
			KESSAI_TIME, KESSAI_NO, SHIHARAI_DATE, SHIHARAI_TIME, NYUKIN_DATE,
			NYUKIN_TIME, NYUKIN_KINGAKU, FURIKOMI_DATE, SEISAN_KIJITU, CVS_CD,
			TEMPO_CD, HARAIDASHI_NO1, HARAIDASHI_NO2, HARAIDASHI_NO3, BANK_CD,
			BANK_NAME, BRANCH_CD, BRANCH_NAME, CUST_NO, KAKUNIN_NO, CHANEL_KBN,
			NOUFUKIN_KBN, NYUURYOKU_KBN, NOUFU_KBN, INSHI_TAX, SHIHARAI_METHOD,
			RESCD, RES };
	
	/** SCエラー・外部IFエラー変換マップ */
	private static final Map<String,String> CHK_ERR_CNV_MAP;
	static
	{
		HashMap<String, String> map = new HashMap<String, String>();
		map.put(ECH0901D010CBSMsg.KSSAI_WAY_DIV_ERR, BILL_METHOD + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.SEIKY_KEI_NO_ERR, SHOPORDER_NO + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.SEIKY_YM_ERR, SHOPORDER_NO + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.SKS_HAKKO_SEQ_ERR, SHOPORDER_NO + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.KSSAI_UK_YMD_ERR, KESSAI_DATE + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.KSSAI_UK_HMS_ERR, KESSAI_TIME + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.KSSAI_UK_NO_ERR, KESSAI_NO + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.PAY_KIGEN_YMD_ERR, SHIHARAI_DATE + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.PAY_KIGEN_HM_ERR, SHIHARAI_TIME + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.NYUKIN_YMD_ERR, NYUKIN_DATE + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.NYUKIN_HM_ERR, NYUKIN_TIME + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.NYUKIN_AMNT_ERR, NYUKIN_KINGAKU + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.SSN_KIGEN_YMD_ERR, SEISAN_KIJITU + PREFIX_ERR_ITEM);
		map.put(ECH0901D010CBSMsg.HRIKOMI_RSV_YMD_ERR, FURIKOMI_DATE + PREFIX_ERR_ITEM);
		CHK_ERR_CNV_MAP = Collections.unmodifiableMap(map);
	}
	/** 英名、和名変換マップ */
	private static final Map<String,String> ENG_JPN_CNV_MAP;
	static
	{
		HashMap<String, String> map = new HashMap<String, String>();
		map.put(VERSION, "バージョン");
		map.put(BILL_METHOD, "決済手段区分");
		map.put(BILL_METHOD_NAME, "決済手段名称");
		map.put(KESSAI_ID, "決済種類コード");
		map.put(KESSAI_NAME, "決済種類名称");
		map.put(SHOP_CD, "契約コード");
		map.put(SYUNO_CO_CD, "収納企業コード");
		map.put(KYOTEN_CD, "拠点コード");
		map.put(SHOPORDER_NO, "請求番号");
		map.put(SEIKYUU_KINGAKU, "請求金額");
		map.put(KESSAI_DATE, "決済受付日");
		map.put(KESSAI_TIME, "決済受付時分秒");
		map.put(KESSAI_NO, "決済受付番号");
		map.put(SHIHARAI_DATE, "支払期限日");
		map.put(SHIHARAI_TIME, "支払期限時分");
		map.put(NYUKIN_DATE, "入金日");
		map.put(NYUKIN_TIME, "入金時分");
		map.put(NYUKIN_KINGAKU, "入金金額");
		map.put(FURIKOMI_DATE, "振込日");
		map.put(SEISAN_KIJITU, "精算期日");
		map.put(CVS_CD, "コンビニコード");
		map.put(TEMPO_CD, "店舗コード");
		map.put(HARAIDASHI_NO1, "払出番号1");
		map.put(HARAIDASHI_NO2, "払出番号2");
		map.put(HARAIDASHI_NO3, "払出番号3");
		map.put(BANK_CD, "金融機関コード");
		map.put(BANK_NAME, "金融機関名");
		map.put(BRANCH_CD, "店舗コード");
		map.put(BRANCH_NAME, "収納機関番号");
		map.put(CUST_NO, "お客様番号");
		map.put(KAKUNIN_NO, "確認番号");
		map.put(CHANEL_KBN, "チャネル区分");
		map.put(NOUFUKIN_KBN, "納付金区分");
		map.put(NYUURYOKU_KBN, "入力区分");
		map.put(NOUFU_KBN, "納付区分");
		map.put(INSHI_TAX, "印紙税");
		map.put(SHIHARAI_METHOD, "支払方法");
		map.put(RESCD, "結果コード");
		map.put(RES, "結果内容");
		ENG_JPN_CNV_MAP = Collections.unmodifiableMap(map);
	}
	
	/** 請求書発行シーケンス；桁数埋め用 */
	private static final String SKS_HAKKO_SEQ_ZERO = "0";
	
	/** 必須チェック・必須（NOT NULL ＝ ○） */
	private static final String HISSU_CHECK_HISSU = "1";
	
	/** 必須チェック・任意（NOT NULL ≠ ○） */
	private static final String HISSU_CHECK_NINI = "0";
	
	/** ドメインチェック・半角数字1 */
	private static final String DOMAIN_CHECK_NUMBER1 = "1";
	
	/** ドメインチェック・半角英数字1 */
	private static final String DOMAIN_CHECK_ENNUMBER1 = "2";
	
	/** ドメインチェック・全角文字1 */
	private static final String DOMAIN_CHECK_EMSIZE1 = "3";
	
	/** ドメインチェック・年月日1 */
	private static final String DOMAIN_CHECK_MONTHDAY1 = "4";
	
	/** ドメインチェック・時分秒1 */
	private static final String DOMAIN_CHECK_HOURMINSEC1 = "5";
	
	/** ドメインチェック・時分1 */
	private static final String DOMAIN_CHECK_HOURMI1 = "6";
	
	/** ドメインチェック・請求番号独自チェック */
	private static final String DOMAIN_CHECK_SEIKY_NO = "7";
	
	/** 桁数チェック・最小値 */
	private static final int LEN_CHECK_MIN = 0;
	
	/** 桁数チェック・最大値 */
	private static final int LEN_CHECK_MAX = 1;
	
	/** バージョン・入金結果通知 */
	private static final String VERSION_NK_RSLT = "310";
	
	/** ステータスコード・正常 */
	private static final String STATUS_CD_NOMAL = "0";
	
	/** ステータスコード・エラー */
	private static final String STATUS_CD_ERR = "1";
	
	// ▲▲▲決済代行会社リアル入金情報登録 定数クラス ▲▲▲

	
	/**
	 * 決済代行会社リアル入金情報登録を行います。
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText ユーザ定義文字列
	 * @return リクエストパラメータ
	 * @throws Throwable 例外が発生した場合
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite addKssaidkCmpNyukin(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(fixedText);

		// ステータスコードに"0"正常を設定
		ccMsg.put(STATUS_CD, STATUS_CD_NOMAL);
		
		// 単項目チェックを行う。
		executeSingleItemChk(ccMsg);
		
		//決済代行会社入金情報登録
		callECH0901D010SC(handle, param, ccMsg, fixedText);
		
		// 単項目チェックエラー処理を行う
		singleItemChkErr(param, fixedText);
		
		return param;
	}
	

	/**
	 * エラーレベルに"400"警告を設定します。
	 * @param param
	 */
	private void setErrLevelWar(IRequestParameterReadWrite param) 
	{
		// ステータスエリア編集
		StatusArea sa = param.getStatusArea();
		
		// エラーレベル
		//v32.00.03 IT1-2017-0000047 Mod Start
//		ErrorLevel errorLevel = ErrorLevel.EL888;
		ErrorLevel errorLevel = ErrorLevel.EL400;
		//v32.00.03 IT1-2017-0000047 Mod End
		StatusInfo si = new StatusInfo(errorLevel, OUTBREAK_AREA.CC);
		sa.setCurrent(si);
		
	}


	/**
	 * チェック処理用サービスインターフェイス作成。<br>
	 * <br>
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return サービスコンポーネント実行用CAANMsg
	 * @exception RequestParameterExceptionがスローされます。
	 */
	@SuppressWarnings("unchecked")
	public  HashMap<String, Object> getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
	throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		List<CAANMsg> templates = new ArrayList<CAANMsg>();
		
		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文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));
		
		// チェック用サービスインターフェイス
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, Arrays.asList(templates));
		return paramMap;
	}
	

	/**
	 * IRequestParameterReadWriteにエラー情報をマッピングする。<br>
	 * <br>
	 * @param param (I) 業務データ取得・書込用I/F
	 * @param templates (I) CAANMsgクラス配列
	 * @param returnCode (I) リターンコード
	 * @param fixedText (I) ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @exception RequestParameterExceptionがスローされます。
	 */
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param, CAANMsg[] templates, int returnCode, String fixedText)
	throws RequestParameterException
	{
		for (int i = 0; i < templates.length; i++)
		{
			editErrorInfoCom(param, templates, returnCode, fixedText);
		}
		return param;
	}
	

	/**
	 * 
	 * @param param
	 * @param templates
	 * @param returnCode
	 * @param dataMapKey
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editErrorInfoCom(IRequestParameterReadWrite param,
														CAANMsg[] templates, 
														int returnCode,
														String dataMapKey) throws RequestParameterException
	{
		// 本来はサービスインターフェイス分の処理が必要
		CAANMsg template = templates[0];
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		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, String> ccMsg = null;
		// ユーザデータ情報
		ccMsg = (HashMap<String, String>)param.getData(dataMapKey);
		
		Iterator<String> it = ccMsg.keySet().iterator();
		while (it.hasNext())
		{
			String key = it.next();
			if (key.endsWith(PREFIX_ERR_ITEM))
			{
				if (!template.isNull(key))
				{
					if (!ccMsg.containsKey(key))
					{
						ccMsg.put(key, template.getString(key));
					}
				}
			}
		}
		return param;
	}

	/**
	 * SC(サービスインターフェイス）を呼び出す。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param mappingData
	 * @return CAANMsg
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg callSC(SessionHandle handle,
							ServiceComponentRequestInvoker scCall,
							IRequestParameterReadWrite param,
							String dataMapKey,
							Object[][] mappingData) throws Exception
	{
		HashMap<String, Object> paramMap = editInMsg(param, mappingData);
		
		Map<?, ?> result = scCall.run(paramMap, handle);
		
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg msg = templates[0];
		
		// リターンコード取得
		int returnCode = (Integer)result.get(JCMConstants.RET_CD_INT_KEY);
		
		int templateStatus = msg.getInt(ECH0901D010CBSMsg.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);
		}
		
		setErrorInf(msg, (HashMap<String, Object>)param.getData(dataMapKey), param);
		
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if (errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(result, errList));
		
		/* ◇処理結果の判定*/
		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();
		Integer status = msg.getInt(JCMConstants.STATUS_INT_KEY);
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(rtnCode) && 0 == status.intValue()))
		{
			
			SCCallException scCallEx = new SCCallException("戻り値不正", rtnCode, status);
			throw scCallEx;
			
		}
		return msg;
	}

	/**
	 * エラー情報を設定します。
	 * 
	 * @param msg
	 * @param map
	 * @param param 
	 * 
	 */
	@SuppressWarnings("unchecked")
	private void setErrorInf(CAANMsg msg, HashMap<String, Object> map, IRequestParameterReadWrite param)
	{
		Iterator<String> msgKey = msg.getSchema().getSchemaKeySet().iterator();
		
		while (msgKey.hasNext())
		{ 
			String key = msgKey.next();
			
			if (key.endsWith(PREFIX_ERR_ITEM))
			{
				if (!msg.isNull(key))
				{
					// ステータスコードに"1"エラーを設定
					map.put(STATUS_CD, STATUS_CD_ERR);
					
					// エラーレベルに"400"警告を設定する
					setErrLevelWar(param);
					
					// SCのエラーを外部IFのエラーに変換して設定
					scErrToOutIfErr(msg, map, key);
					
					// シスログへの出力を行う。
					scErrSyslog(msg, key);
				}
			}
		}
	}
	

	/**
	 * 共通項目のメッセージを作成します。
	 * @param param リクエストパラメータ
	 * @param mappingData マッピングデータ
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException リクエストパラメータの操作でエラーが発生した場合
	 */
	private HashMap<String, Object> editInMsg(IRequestParameterReadWrite param,
												Object[][] mappingData) 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));

		String svcIf = (String)mappingData[0][1];

		CAANMsg template = new CAANMsg(String.format("eo.ejb.cbs.cbsmsg.%sCBSMsg", svcIf));

		// オペレータID
		template.set(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));

		// 運用日付
		template.set(JCMConstants.OPERATE_DATE_KEY, param.getControlMapData(SCControlMapKeys.OPE_DATE));

		// 運用日時
		template.set(JCMConstants.OPERATE_DATETIME_KEY, param.getControlMapData(SCControlMapKeys.OPE_TIME));
		
		for (int i = 0; i < mappingData.length; i++)
		{
			if ("".equals(mappingData[i][1]))
			{
				template.setNull((String)mappingData[i][0]);
			}
			else
			{
				template.set((String)mappingData[i][0], mappingData[i][1]);
			}
		}

		CAANMsg[] templates = new CAANMsg[1];

		templates[0] = template;

		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);

		return paramMap;
	}

	/**
	 * 決済代行会社入金情報の編集を行います。
	 * 編集例：310,03,コンビニエンスストア・・・
	 * @param ccMsg 
	 */
	private String makeKsdkcpNkif(HashMap<String, Object> ccMsg)
	{
		StringBuilder sb = new StringBuilder();
		
		// 項目の件数分ループする
		for (int i = 0; i < KSDKCP_NKIF_OPUT_JUN.length; i++) 
		{
			// 出力順にレコードを設定する
			sb.append((String) ccMsg.get(KSDKCP_NKIF_OPUT_JUN[i]));
			
			// 最終レコード以外の場合「,」（コンマ）を付与する
			if (KSDKCP_NKIF_OPUT_JUN.length != i) 
			{
				sb.append(JACStrConst.COMMA);
			}
		}
		return sb.toString();
	}
	

	/**
	 * 単項目チェック処理の呼出を行います。
	 * @param ccMsg
	 */
	private void executeSingleItemChk(HashMap<String, Object> ccMsg)
	{
		
		// バージョン 必須あり ドメイン：半角英数字1 桁：固定長：3
		singleItemChk(ccMsg, VERSION, HISSU_CHECK_HISSU, DOMAIN_CHECK_ENNUMBER1, new int[] { 3, 3 });
		
		// 決済手段区分 必須あり ドメイン：半角数字1 桁：固定長：2
		singleItemChk(ccMsg, BILL_METHOD, HISSU_CHECK_HISSU, DOMAIN_CHECK_NUMBER1, new int[] { 2, 2 });
		
		// 決済手段名称 必須なし ドメイン：全角 桁：可変長：最小：1 最大：25
		singleItemChk(ccMsg, BILL_METHOD_NAME, HISSU_CHECK_NINI, DOMAIN_CHECK_EMSIZE1, new int[] { 1, 25 });
		
		// 決済種類コード 必須あり ドメイン：半角数字1 桁：固定長：4
		singleItemChk(ccMsg, KESSAI_ID, HISSU_CHECK_HISSU, DOMAIN_CHECK_NUMBER1, new int[] { 4, 4 });
		
		// 決済種類名称 必須なし ドメイン：全角 桁：可変長：最小：1 最大：25
		singleItemChk(ccMsg, KESSAI_NAME, HISSU_CHECK_NINI, DOMAIN_CHECK_EMSIZE1, new int[] { 1, 25 });
		
		// 契約コード 必須あり ドメイン：半角英数字1 桁：固定長：7
		singleItemChk(ccMsg, SHOP_CD, HISSU_CHECK_HISSU, DOMAIN_CHECK_ENNUMBER1, new int[] { 7, 7 });
		
		// 収納企業コード 必須あり ドメイン：半角英数字1 桁：可変長：最小：1 最大：8
		singleItemChk(ccMsg, SYUNO_CO_CD, HISSU_CHECK_HISSU, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 8 });
		
		// 拠点コード 必須なし ドメイン：半角数字1 桁：可変長：最小：1 最大：5
		singleItemChk(ccMsg, KYOTEN_CD, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 1, 5 });
		
		// 請求番号 必須あり ドメイン：請求番号独自チェック 桁：固定長：17
		singleItemChk(ccMsg, SHOPORDER_NO, HISSU_CHECK_HISSU, DOMAIN_CHECK_SEIKY_NO, new int[] { 17, 17 });
		
		// 請求金額 必須あり ドメイン：半角数字1 桁：可変長：最小：1 最大：13
		singleItemChk(ccMsg, SEIKYUU_KINGAKU, HISSU_CHECK_HISSU, DOMAIN_CHECK_NUMBER1, new int[] { 1, 13 });
		
		// 決済受付日 必須あり ドメイン：年月日1 桁：固定長：8
		singleItemChk(ccMsg, KESSAI_DATE, HISSU_CHECK_HISSU, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
		
		// 決済受付時分秒 必須あり ドメイン：時分秒1 桁：固定長：6
		singleItemChk(ccMsg, KESSAI_TIME, HISSU_CHECK_HISSU, DOMAIN_CHECK_HOURMINSEC1, new int[] { 6, 6 });
		
		// 決済受付番号 必須あり ドメイン：半角数字1 桁：固定長：14
		singleItemChk(ccMsg, KESSAI_NO, HISSU_CHECK_HISSU, DOMAIN_CHECK_NUMBER1, new int[] { 14, 14 });
		
		// 支払期限日 必須なし ドメイン：年月日1 桁：固定長：8
		singleItemChk(ccMsg, SHIHARAI_DATE, HISSU_CHECK_NINI, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
		
		// 支払期限時分 必須なし ドメイン：時分1 桁：固定長：4
		singleItemChk(ccMsg, SHIHARAI_TIME, HISSU_CHECK_NINI, DOMAIN_CHECK_HOURMI1, new int[] { 4, 4 });
		
		// 入金日 必須あり ドメイン：年月日1 桁：固定長：8
		singleItemChk(ccMsg, NYUKIN_DATE, HISSU_CHECK_HISSU, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
		
		// 入金時分 必須あり ドメイン：時分1 桁：固定長：4
		singleItemChk(ccMsg, NYUKIN_TIME, HISSU_CHECK_HISSU, DOMAIN_CHECK_HOURMI1, new int[] { 4, 4 });
		
		// 入金金額 必須あり ドメイン：半角数字1 桁：可変長：最小：1 最大：13
		singleItemChk(ccMsg, NYUKIN_KINGAKU, HISSU_CHECK_HISSU, DOMAIN_CHECK_NUMBER1, new int[] { 1, 13 });
		
//v32.00.02 2017/05/15 Mod Start
		// 振込日 必須なし ドメイン：年月日1 桁：固定長：8
//		singleItemChk(ccMsg, FURIKOMI_DATE, HISSU_CHECK_HISSU, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
		singleItemChk(ccMsg, FURIKOMI_DATE, HISSU_CHECK_NINI, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
//v32.00.02 2017/05/15 Mod End
		
		// 精算期日 必須なし ドメイン：年月日1 桁：固定長：8
		singleItemChk(ccMsg, SEISAN_KIJITU, HISSU_CHECK_NINI, DOMAIN_CHECK_MONTHDAY1, new int[] { 8, 8 });
		
		// コンビニコード 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：10
		singleItemChk(ccMsg, CVS_CD, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 10 });
		
		// 店舗コード 必須なし ドメイン：半角数字1 桁：可変長：最小：1 最大：8
		singleItemChk(ccMsg, TEMPO_CD, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 1, 8 });
		
		// 払出番号1 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：256
		singleItemChk(ccMsg, HARAIDASHI_NO1, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 256 });
		
		// 払出番号2 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：256
		singleItemChk(ccMsg, HARAIDASHI_NO2, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 256 });
		
		// 払出番号3 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：256
		singleItemChk(ccMsg, HARAIDASHI_NO3, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 256 });
		
		// 金融機関コード 必須なし ドメイン：半角数字1 桁：可変長：最小：1 最大：10
		singleItemChk(ccMsg, BANK_CD, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 1, 10 });
		
		// 金融機関名 必須なし ドメイン：全角 桁：可変長：最小：1 最大：25
		singleItemChk(ccMsg, BANK_NAME, HISSU_CHECK_NINI, DOMAIN_CHECK_EMSIZE1, new int[] { 1, 25 });
		
		// 店舗コード 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：8
		singleItemChk(ccMsg, BRANCH_CD, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 8 });
		
		// 収納機関番号 必須なし ドメイン：半角数字1 桁：固定長：5
		singleItemChk(ccMsg, BRANCH_NAME, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 5, 5 });
		
		// お客様番号 必須なし ドメイン：半角数字1 桁：可変長：最小：1 最大：15
		singleItemChk(ccMsg, CUST_NO, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 1, 15 });
		
		// 確認番号 必須なし ドメイン：半角数字1 桁：固定長：6
		singleItemChk(ccMsg, KAKUNIN_NO, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 6, 6 });
		
		// チャネル区分 必須なし ドメイン：半角数字1 桁：固定長：2
		singleItemChk(ccMsg, CHANEL_KBN, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 2, 2 });
		
		// 納付金区分 必須なし ドメイン：半角英数字1 桁：固定長：2
		singleItemChk(ccMsg, NOUFUKIN_KBN, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 2, 2 });
		
		// 入力区分 必須なし ドメイン：半角英数字1 桁：固定長：2
		singleItemChk(ccMsg,  NYUURYOKU_KBN, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 2, 2 });
		
		// 納付区分 必須なし ドメイン：半角英数字1 桁：可変長：最小：1 最大：16
		singleItemChk(ccMsg, NOUFU_KBN, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 16 });
		
		// 印紙税 必須なし ドメイン：半角数字1 桁：可変長：最小：1 最大：3
		singleItemChk(ccMsg, INSHI_TAX, HISSU_CHECK_NINI, DOMAIN_CHECK_NUMBER1, new int[] { 1, 3 });
		
		// 支払方法 必須なし ドメイン：半角英数字1 桁：固定長：1
		singleItemChk(ccMsg, SHIHARAI_METHOD, HISSU_CHECK_NINI, DOMAIN_CHECK_ENNUMBER1, new int[] { 1, 1 });
		
		// 結果コード 必須あり ドメイン：半角英数字1 桁：固定長：6
		singleItemChk(ccMsg, RESCD, HISSU_CHECK_HISSU, DOMAIN_CHECK_ENNUMBER1, new int[] { 6, 6 });
		
		// 結果内容 必須なし ドメイン：全角 桁：可変長：最小：1 最大：128
		singleItemChk(ccMsg, RES, HISSU_CHECK_NINI, DOMAIN_CHECK_EMSIZE1, new int[] { 1, 128 });
	}
	

	/**
	 * 単項目チェックを行います。
	 * @param ccMsg 
	 * @param key
	 * @param hissuCheckKbn 1：必須項目 0：任意項目
	 * @param domainCheckKbn 1：半角数字1 2：半角英数字1 3：全角文字1
	 * @param lenCheckKbn lenCheck[0]：最小値 lenCheck[1]最大値
	 * @return
	 */
	private void singleItemChk(HashMap<String, Object> ccMsg, String key, String hissuCheckKbn, String domainCheckKbn, int lenCheckKbn[])
	{
		// チェック対象の値を取得
		String value = (String)ccMsg.get(key);
		
		// 必須チェック・値の存在チェック
		if(JCHStringUtil.isNullBlank(value))
		{
			// 必須チェック（必須項目の場合必須チェックエラー）
			if(HISSU_CHECK_HISSU.equals(hissuCheckKbn))
			{
				// 必須チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E1);
				
				// シスログ通知
				outErrLog(API_MSG_ID_1, key, null);
				return;
			}
			// 任意項目の場合は後続の処理を行わない。
			else
			{
				return;
			}
		}
		
		// ドメインチェック
		if(DOMAIN_CHECK_NUMBER1.equals(domainCheckKbn))
		{
			//半角数字1
			if(!HalfCharCheck.isNumber1Check(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);

				return;
			}
		}
		else if(DOMAIN_CHECK_ENNUMBER1.equals(domainCheckKbn))
		{
			//半角英数字1
			if(!HalfCharCheck.isEnNumber1Check(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);
				
				return;
			}
		}
		else if(DOMAIN_CHECK_EMSIZE1.equals(domainCheckKbn))
		{
			//全角1
			if(!EmsizeCharCheck.isEmsize1Check(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);
				
				return;
			}
		}
		else if(DOMAIN_CHECK_MONTHDAY1.equals(domainCheckKbn))
		{
			//年月日1
			if(!DatetimeCheck.isDateCheck(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);
				
				return;
			}
		}
		else if(DOMAIN_CHECK_HOURMINSEC1.equals(domainCheckKbn))
		{
			//時分秒1
			if(!DatetimeCheck.isHourMinSec1Check(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);
				
				return;
			}
		}
		else if(DOMAIN_CHECK_HOURMI1.equals(domainCheckKbn))
		{
			//時分1
			if(!DatetimeCheck.isHourMin1(value))
			{
				// 形式チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
				
				// シスログ通知
				outErrLog(API_MSG_ID_2, key, value);
				
				return;
			}
		}
		// 請求番号独自チェック
		else if(DOMAIN_CHECK_SEIKY_NO.equals(domainCheckKbn))
		{
			// 17桁でない場合はチェックを未実施
			if(value.length() == 17)
			{
				String seikyKeiNo  = value.substring(0, 10);
				String seikyYm     = value.substring(10, 16);
				String sksHakkoSeq = value.substring(16);
				
				//半角数字1（1桁目から10桁目（請求契約番号））
				if(!HalfCharCheck.isNumber1Check(seikyKeiNo))
				{
					// 形式チェックエラー
					ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
					
					// シスログ通知
					outErrLog(API_MSG_ID_2, key, value);
					
					return;
				}
				//年月1（11桁目から16桁目（請求年月））
				if(!DatetimeCheck.isYearMonthCheck(seikyYm))
				{
					// 形式チェックエラー
					ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
					
					// シスログ通知
					outErrLog(API_MSG_ID_2, key, value);
					
					return;
				}
				//半角数字1（17桁目（請求書発行シーケンス））
				if(!HalfCharCheck.isNumber1Check(sksHakkoSeq))
				{
					// 形式チェックエラー
					ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E2);
					
					// シスログ通知
					outErrLog(API_MSG_ID_2, key, value);
					
					return;
				}
			}
		}
		
		// 桁数チェック
		int min = lenCheckKbn[LEN_CHECK_MIN];
		int max = lenCheckKbn[LEN_CHECK_MAX];
		
		if(min == max)
		{
			// 桁数1
			if(!LengthCheck.isLength1Check(value, max))
			{
				// 桁数チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E3);
				
				// シスログ通知
				outErrLog(API_MSG_ID_3, key, value);
				
				return;
			}
		}
		else
		{
			// 桁数2
			if(!LengthCheck.isLength2Check(value, min, max))
				{
				// 桁数チェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E3);
				
				// シスログ通知
				outErrLog(API_MSG_ID_3, key, value);
				
				return;
				}
		}
		
		// 項目固有チェック・決済手段区分
		if(BILL_METHOD.equals(key))
		{
			// 決済手段区分 単項目チェック
			if (!(JACStrConst.KESSAI_WAY_DIV_CVS.equals(value))
					&& !(JACStrConst.KESSAI_WAY_DIV_CRE.equals(value))
					&& !(JACStrConst.KESSAI_WAY_DIV_ATM.equals(value)))
			{
				// リファレンスチェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E4);
				
				// シスログ通知
				outErrLog(API_MSG_ID_4, key, value);
				return;
			}
		}
		// 項目固有チェック・バージョン
		if(VERSION.equals(key))
		{
			// バージョン 単項目チェック
			if(!(VERSION_NK_RSLT.equals(value)))
			{
				// リファレンスチェックエラー
				ccMsg.put(key.concat(PREFIX_ERR_ITEM), TMCK_ERR_E4);
				// シスログ通知
				outErrLog(API_MSG_ID_4, key, value);
				return;
			}
		}
	}
	

	/**
	 * 単項目チェックエラー処理を行います。
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private boolean getSingleItemChkErrFlg(IRequestParameterReadWrite param, String fixedText) throws RequestParameterException
	{

		HashMap<String, String> ccMsg = null;
		
		// ユーザデータ情報
		ccMsg = (HashMap<String, String>)param.getData(fixedText);
		
		for (String str :ccMsg.keySet())
		{
			if(str.endsWith(PREFIX_ERR_ITEM))
			{
				return true;
			}
		}
		return false;
	}
	

	/**
	 * 単項目チェックエラー処理を行います。
	 * @param ccMsg 
	 * @throws SCCallException 
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	private void singleItemChkErr(IRequestParameterReadWrite param, String fixedText) throws SCCallException, RequestParameterException 
	{

		HashMap<String, String> ccMsg = null;

		// ユーザデータ情報
		ccMsg = (HashMap<String, String>)param.getData(fixedText);
		
		HashMap<String, Object> map = (HashMap<String, Object>)param.getData(fixedText);
		
		for (String str :ccMsg.keySet())
		{
			if(str.endsWith(PREFIX_ERR_ITEM))
			{
				// BPにサービスコンポーネントのステータスを設定する。
				String formatStatus = String.format("%1$04d", 1000);
				
				String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
				
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
				
				param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
				
				// ステータスコードに"1"エラーを設定
				map.put(STATUS_CD, STATUS_CD_ERR);
				
				// エラーレベルに"400"警告を設定する
				setErrLevelWar(param);
				
			}
		}
	}
	

	/**
	 * 決済代行会社リアル入金情報登録の呼出を行います。
	 * @param handle
	 * @param param
	 * @param ccMsg
	 * @param fixedText
	 * @param singleChkErrFlg 
	 * @return 
	 * @throws Exception
	 */
	private CAANMsg callECH0901D010SC(SessionHandle handle, IRequestParameterReadWrite param, HashMap<String, Object> ccMsg,
			String fixedText) throws Exception {

		HashMap<String, String> paramList = new HashMap<String, String>();
		
		// パラメータの設定
		setParam(param, ccMsg, fixedText, paramList);
		
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない）
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// 決済代行会社リアル入金情報登録の上りマッピング
		Object[][] ECH0901D010In =
		{
			{ECH0901D010CBSMsg.TEMPLATEID,                   TEMPLATE_ID_ECH0901D010},
			{ECH0901D010CBSMsg.FUNC_CODE,                    JPCModelConstant.FUNC_CD_1},
			{ECH0901D010CBSMsg.KSDKCP_NKIF_RCV_SBT_CD,       JACStrConst.KESSAI_NYUKIN_INFO_TYPE_CD_REAL},
			{ECH0901D010CBSMsg.NYUKIN_ADD_STAT_CD,           paramList.get(ECH0901D010CBSMsg.NYUKIN_ADD_STAT_CD)},
			{ECH0901D010CBSMsg.KSSAI_WAY_DIV,                paramList.get(ECH0901D010CBSMsg.KSSAI_WAY_DIV)},
			{ECH0901D010CBSMsg.SEIKY_KEI_NO,                 paramList.get(ECH0901D010CBSMsg.SEIKY_KEI_NO)},
			{ECH0901D010CBSMsg.SEIKY_YM,                     paramList.get(ECH0901D010CBSMsg.SEIKY_YM)},
			{ECH0901D010CBSMsg.SKS_HAKKO_SEQ,                paramList.get(ECH0901D010CBSMsg.SKS_HAKKO_SEQ)},
			{ECH0901D010CBSMsg.KSSAI_UK_YMD,                 paramList.get(ECH0901D010CBSMsg.KSSAI_UK_YMD)},
			{ECH0901D010CBSMsg.KSSAI_UK_HMS,                 paramList.get(ECH0901D010CBSMsg.KSSAI_UK_HMS)},
			{ECH0901D010CBSMsg.KSSAI_UK_NO,                  paramList.get(ECH0901D010CBSMsg.KSSAI_UK_NO)},
			{ECH0901D010CBSMsg.PAY_KIGEN_YMD,                paramList.get(ECH0901D010CBSMsg.PAY_KIGEN_YMD)},
			{ECH0901D010CBSMsg.PAY_KIGEN_HM,                 paramList.get(ECH0901D010CBSMsg.PAY_KIGEN_HM)},
			{ECH0901D010CBSMsg.NYUKIN_YMD,                   paramList.get(ECH0901D010CBSMsg.NYUKIN_YMD)},
			{ECH0901D010CBSMsg.NYUKIN_HM,                    paramList.get(ECH0901D010CBSMsg.NYUKIN_HM)},
			{ECH0901D010CBSMsg.NYUKIN_AMNT,                  paramList.get(ECH0901D010CBSMsg.NYUKIN_AMNT)},
			{ECH0901D010CBSMsg.SSN_KIGEN_YMD,                paramList.get(ECH0901D010CBSMsg.SSN_KIGEN_YMD)},
			{ECH0901D010CBSMsg.HRIKOMI_RSV_YMD,              paramList.get(ECH0901D010CBSMsg.HRIKOMI_RSV_YMD)},
			{ECH0901D010CBSMsg.SEIYK_YMD,                    null},
			{ECH0901D010CBSMsg.SHUNO_YMD,                    null},
			{ECH0901D010CBSMsg.SHUNO_HM,                     null},
			// v32.00.01 IT1-2017-0000026 Mod Start
//			{ECH0901D010CBSMsg.KSDKCP_NKIF_TRN_DTM,          null},
			{ECH0901D010CBSMsg.KSDKCP_NKIF_TRN_DTM,          paramList.get(ECH0901D010CBSMsg.KSDKCP_NKIF_TRN_DTM)},
			// v32.00.01 IT1-2017-0000026 Mod End
			{ECH0901D010CBSMsg.KSDKCP_NKIF,                  paramList.get(ECH0901D010CBSMsg.KSDKCP_NKIF)},
		};

		// サービスIF実行
		CAANMsg ECH0901D010Msg1List = callSC(handle, scCall, param, fixedText, ECH0901D010In);

		return ECH0901D010Msg1List;
		
	}
	

	/**
	 * 決済代行会社リアル入金情報登録へのパラメータ設定を行います。
	 * @param param
	 * @param ccMsg
	 * @param fixedText
	 * @param paramList
	 * @throws RequestParameterException
	 */
	private void setParam(IRequestParameterReadWrite param, HashMap<String, Object> ccMsg, String fixedText,
		HashMap<String, String> paramList) throws RequestParameterException 
		{
			// 請求番号
			String shoporder_no = (String)ccMsg.get(SHOPORDER_NO);
			
			// 単項目チェックエラー有無によって判定を行う。
			if(getSingleItemChkErrFlg(param, fixedText))
			{
				//エラー有の場合、必須項目にはダミー値を設定する。
				paramList.put(ECH0901D010CBSMsg.NYUKIN_ADD_STAT_CD,           JACStrConst.NYUKIN_ADD_STAT_CD_MI_ERR);
				paramList.put(ECH0901D010CBSMsg.KSSAI_WAY_DIV,                JACStrConst.CH0901_KSSAI_WAY_DIV_DUMMY);
				paramList.put(ECH0901D010CBSMsg.SEIKY_KEI_NO,                 JACStrConst.CH0901_SEIKY_KEI_NO_DUMMY);
				paramList.put(ECH0901D010CBSMsg.SEIKY_YM,                     JACStrConst.CH0901_SEIKY_YM_DUMMY);
				paramList.put(ECH0901D010CBSMsg.SKS_HAKKO_SEQ,                JACStrConst.CH0901_SKS_HAKKO_SEQ_DUMMY);
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_YMD,                 null);
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_HMS,                 null);
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_NO,                  null);
				paramList.put(ECH0901D010CBSMsg.PAY_KIGEN_YMD,                null);
				paramList.put(ECH0901D010CBSMsg.PAY_KIGEN_HM,                 null);
				paramList.put(ECH0901D010CBSMsg.NYUKIN_YMD,                   null);
				paramList.put(ECH0901D010CBSMsg.NYUKIN_HM,                    null);
				paramList.put(ECH0901D010CBSMsg.NYUKIN_AMNT,                  null);
				paramList.put(ECH0901D010CBSMsg.SSN_KIGEN_YMD,                null);
				paramList.put(ECH0901D010CBSMsg.HRIKOMI_RSV_YMD,              null);
			}
			else
			{
				
				//v32.00.02 2017/05/11 Add Start
				//振込予定年月日設定時に利用するため決済手段区分を取得
				String kssaiWyDiv = (String)ccMsg.get(BILL_METHOD);
				
				//振込予定年月日設定用
				String hrikomiRsvYmd = "";
				
				//振込予定年月日算出に利用するため入金年月日を取得
				String nyukinYmd = (String)ccMsg.get(NYUKIN_DATE);
				
				if(!JACStrConst.KESSAI_WAY_DIV_CVS.equals(kssaiWyDiv))
				{
					hrikomiRsvYmd = JACCommonUtil.getKsdkcpCvsPayRsvYmd(nyukinYmd);
				}
					
				
				//v32.00.02 2017/05/11 Add End
				
				// エラー無の場合、入力電文を編集して設定する。
				paramList.put(ECH0901D010CBSMsg.NYUKIN_ADD_STAT_CD,           JACStrConst.NYUKIN_ADD_STAT_CD_MI);
				paramList.put(ECH0901D010CBSMsg.KSSAI_WAY_DIV,                (String)ccMsg.get(BILL_METHOD));
				paramList.put(ECH0901D010CBSMsg.SEIKY_KEI_NO,                 shoporder_no.substring(0, 10));
				paramList.put(ECH0901D010CBSMsg.SEIKY_YM,                     shoporder_no.substring(10, 16));
				paramList.put(ECH0901D010CBSMsg.SKS_HAKKO_SEQ,                SKS_HAKKO_SEQ_ZERO + shoporder_no.substring(16));
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_YMD,                 (String)ccMsg.get(KESSAI_DATE));
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_HMS,                 (String)ccMsg.get(KESSAI_TIME));
				paramList.put(ECH0901D010CBSMsg.KSSAI_UK_NO,                  (String)ccMsg.get(KESSAI_NO));
				paramList.put(ECH0901D010CBSMsg.PAY_KIGEN_YMD,                (String)ccMsg.get(SHIHARAI_DATE));
				paramList.put(ECH0901D010CBSMsg.PAY_KIGEN_HM,                 (String)ccMsg.get(SHIHARAI_TIME));
				paramList.put(ECH0901D010CBSMsg.NYUKIN_YMD,                   (String)ccMsg.get(NYUKIN_DATE));
				paramList.put(ECH0901D010CBSMsg.NYUKIN_HM,                    (String)ccMsg.get(NYUKIN_TIME));
				paramList.put(ECH0901D010CBSMsg.NYUKIN_AMNT,                  (String)ccMsg.get(NYUKIN_KINGAKU));
				paramList.put(ECH0901D010CBSMsg.SSN_KIGEN_YMD,                (String)ccMsg.get(SEISAN_KIJITU));
//v32.00.02 2017/05/11 Mod Start
//				paramList.put(ECH0901D010CBSMsg.HRIKOMI_RSV_YMD,              (String)ccMsg.get(FURIKOMI_DATE));
				paramList.put(ECH0901D010CBSMsg.HRIKOMI_RSV_YMD,              hrikomiRsvYmd);
//v32.00.03 2017/05/11 Mod End
			}
			// v32.00.01 IT1-2017-0000026 Add Start
			paramList.put(ECH0901D010CBSMsg.KSDKCP_NKIF_TRN_DTM,          JCCBPCommon.getOnlineOpeDateTime(null));
			// v32.00.01 IT1-2017-0000026 Add End
			paramList.put(ECH0901D010CBSMsg.KSDKCP_NKIF,                  makeKsdkcpNkif(ccMsg));
		}
	

	/**
	 * エラーマッピングを行い、取得したkeyでMapに設定します。
	 * @param msg
	 * @param map 
	 * @param key
	 */
	private void scErrToOutIfErr(CAANMsg msg, HashMap<String, Object> map, String key)
	{
		// SCで発生したエラーが外部IFエラーへの変換対象の場合、変換を行って設定します。
			map.put(convScErrToCCErr(key), msg.getString(key));
	}
	
	

	/**
	 * SCのエラーを外部IFのエラーとマッピングを行います。
	 * @param key キー情報
	 * @return 変換対象の場合：変換後の値、変換対象外の場合：入力値
	 */
	private String convScErrToCCErr(String key) 
	{
		// チェックエラー変換マップにkeyが存在する場合は取得したキーを返却します。
		if (CHK_ERR_CNV_MAP.get(key) != null)
		{
			return CHK_ERR_CNV_MAP.get(key);
		}
		// 存在しない場合は、入力のキーをそのまま返却します。
		else
		{
			return key;
		}
	}
	

	/**
	 * SCにてエラー発生時のシスログへの出力を行います。
	 * @param msg
	 * @param key
	 */
	private void scErrSyslog(CAANMsg msg, String key) 
	{
		String errCd = msg.getString(key);
		String msgId = null;
		String bind2 = msg.getString(key.replace(PREFIX_ERR_ITEM, JACStrConst.KARA_MOJI));
		
		// エラーコードがE1の場合、必須チェックエラーメッセージを設定
		if(TMCK_ERR_E1.equals(errCd))
		{	
			msgId = API_MSG_ID_1;
			bind2 = null;
		}
		// エラーコードがE2の場合、入力文字種チェックエラーメッセージを設定
		else if(TMCK_ERR_E2.equals(errCd))
		{	
			msgId = API_MSG_ID_2;
		}
		// エラーコードがE3の場合、入力文字列長チェックエラーメッセージを設定
		else if(TMCK_ERR_E3.equals(errCd))
		{	
			msgId = API_MSG_ID_3;
		}
		// エラーコードがE4の場合、業務固有チェックエラーメッセージを設定
		else if(TMCK_ERR_E4.equals(errCd))
		{	
			msgId = API_MSG_ID_4;
		}
		// 上記以外の場合、シスログ通知を行わない。
		else
		{
			return;
		}
		// シスログ通知
		outErrLog(msgId, convScErrToCCErr(key), bind2);
	}
	

	/**
	 * シスログ出力用のメッセージを作成します。
	 * @param msgId メッセージID
	 * @param bind1 メッセージバインド変数（%1%)
	 * @param bind2 メッセージバインド変数（%2%)
	 */
	private static void outErrLog(String msgId, String bind1, String bind2)
	{
		//bind1に"_err"が含まれている場合は取り除く（SCエラー時の考慮）
		bind1 = bind1.replace(PREFIX_ERR_ITEM, JACStrConst.KARA_MOJI);
		String message = null;
		
		if(API_MSG_ID_1.equals(msgId))
		{	
			// %1%が設定されていません。
			message = ENG_JPN_CNV_MAP.get(bind1) + "が設定されていません。";
		}
		else if(API_MSG_ID_2.equals(msgId))
		{	
			//連携された値が型式に合っていません。　%1% %2%
			message = "連携された値が型式に合っていません。　" + ENG_JPN_CNV_MAP.get(bind1)  + " " + bind2;
		}
		else if(API_MSG_ID_3.equals(msgId))
		{	
			//文字列長が合っていません。　%1% %2%
			message = "文字列長が合っていません。　" + ENG_JPN_CNV_MAP.get(bind1)  + " " + bind2;
		}
		else if(API_MSG_ID_4.equals(msgId))
		{	
			//連携された値が不正です。　%1% %2%
			message = "連携された値が不正です。　" + ENG_JPN_CNV_MAP.get(bind1)  + " " + bind2;
		}
	
		// メッセージログ（システムログ）にメッセージIDに該当するメッセージを出力する
		printSyslog4Err(CHIFE522, msgId, message);
	}
	
	/**
	 * シスログ出力
	 * @param proId プログラムID
	 * @param msgId メッセージID
	 * @param msg   メッセージ文字列
	 */
	private static void printSyslog4Err(String proId, String msgId, String msg)
	{
	
		String sysdate = new SimpleDateFormat(FMT_YMDHMSS).format(new Date(System.currentTimeMillis()));
		HashMap<String, Object> propMap = new HashMap<String, Object>();
	
		propMap.put(JCCSuperComExecUtil.EXEC_BUFF_SIZE, JCMAPLConstMgr.getString(JCCSuperComExecUtil.EXEC_BUFF_SIZE));
		propMap.put(JCCSuperComExecUtil.EXEC_PERMIT_MEMORY, JCMAPLConstMgr.getString(JCCSuperComExecUtil.EXEC_PERMIT_MEMORY));
		propMap.put(JCCSyslogFormat.SYSLOG_FOMAT_PTN_KEY, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_FOMAT_PTN_KEY));
		propMap.put(JCCSyslogFormat.SYSLOG_MAILING_ID_KEY, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_MAILING_ID_KEY));
		propMap.put(JCCSyslogFormat.SYSLOG_OUT_DIR_OPTION, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_OUT_DIR_OPTION));
		JCCSyslogFormat.logger(proId, msgId, sysdate, msg, WAR, propMap);
	}
}
