/*********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *	システム名			：eo顧客基幹システム
 *	モジュール名		：JBSbatCNCardKssaiCancelYokyu
 *	ソースファイル名	：JBSbatCNCardKssaiCancelYokyu.java
 *	作成者				：FJ)北村
 *	作成日				：2022年05月02日
 *＜機能概要＞
 *　カード決済キャンセル要求処理部品です。
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *	v58.00.00	2022/05/02  FJ)北村		新規作成
**	v58.00.01	2022/07/26  FJ)北村		【IT1-2022-0000040】決済ID不正
 *********************************************************************/
package eo.business.service;

import java.util.HashMap;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCNBatCommon;
import eo.business.util.file.JBSbatCNIFM015;
import eo.business.util.file.JBSbatCNLST01501;
import eo.business.util.table.JBSbatCN_T_CONTJIGYO_CRECA;
import eo.business.util.table.JBSbatKK_M_CRECARD_COMP;
import eo.common.constant.JPCBatchMessageConstant;
import eo.common.util.JPCUtilCommon;
import eo.framework.application.JBSbatBusinessError;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.util.JCCBatchEsbInterface;

/**
 * (クラスの機能概要) <p>
 *<BR>
 * @author 富士通
 */
public class JBSbatCNCardKssaiCancelYokyu extends JBSbatBusinessService
{
	/** テーブル(クレジットカード会社)*/
	private static final String D_TBL_NAME_KK_M_CRECARD_COMP = "KK_M_CRECARD_COMP";

	/** SQL定義キー(CN_SELECT_004)*/
	private static final String KK_M_CRECARD_COMP_CN_SELECT_004 = "CN_SELECT_004";

	/** テーブル(コンテンツ事業クレジットカード)*/
	private static final String D_TBL_NAME_CN_T_CONTJIGYO_CRECA = "CN_T_CONTJIGYO_CRECA";

	/** クレジットカード会社マップ */
	private HashMap<String, Object> crecardCompInfoMap = null;

	/** テーブルアクセスクラス(クレジットカード会社)*/
	private JBSbatSQLAccess db_KK_M_CRECARD_COMP = null;

	/** テーブルアクセスクラス(コンテンツ事業クレジットカード)*/
	private JBSbatSQLAccess db_CN_T_CONTJIGYO_CRECA = null;

	/** マーチャント取引ID */
	private static final String PARAM_MERCHANT_DEAL_ID = "py_trading_id";

	/** 決済ID */
	private static final String PARAM_KSSAI_ID = "py_payment_id";

	/** USECASE */
	private static final String USECASE_ID = "CNSV0060";

	/** OPERATION */
	private static final String OPERATION_ID = "CNSV0060OP";

	/** CCキー */
	private static final String CNSV006001CC = "CNSV006001CC";

	/** 処理結果コード */
	private static final String PARAM_RESULT_CD = "py_resultcode";

	/** レスポンスコード */
	private static final String PARAM_RESPONSE_CODE = "py_response_code";

	/** レスポンス詳細 */
	private static final String PARAM_RESPONSE_DETAIL = "py_response_detail";

	/** オーソリエラー区分:[2:カード決済キャンセルオーソリ] */
	private static final String PARAM_AuthoriErrorKbn_2 = "2:カード決済キャンセルオーソリ";

	/** オーソリ審査結果（正常） */
	private final static String AUTH_RESULT_AUTHOK = "0000000";

	/** サービスIFのリターンコード(正常) */
	private static final String RETURN_CODE_SUCCESS = "0000";

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_KK_M_CRECARD_COMP = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_M_CRECARD_COMP);
		db_CN_T_CONTJIGYO_CRECA = new JBSbatSQLAccess(commonItem, D_TBL_NAME_CN_T_CONTJIGYO_CRECA);

		// クレジットカード会社情報マップ作成
		crecardCompInfoMap = makeCrecardCompInfoMap();
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @param outputInItem 入力情報
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputInItem) throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		if (inMap != null) {
			super.logPrint.printDebugLog("execute_START");
			String kssai_id = inMap.getString(JBSbatCNIFM015.KSSAI_ID);	// 決済ID
			// 決済IDの設定がない場合処理をスキップする。
			if (JCNBatCommon.isNotNullCheck(kssai_id)) 
			{
				// クレジット会社情報取得
				String crecardCompCd = inMap.getString(JBSbatCNIFM015.CARD_BRAND_COMP_CD);	// カードブランド会社カード
				HashMap<String, String> crecardCompInfo = selectCrecardCompInfo(crecardCompCd);
				String crecardCompNm = crecardCompInfo.get(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_NM); // クレジットカード会社名

				// サービスを呼び出すためにCCのマップを作成
				HashMap<String, Object> ccMap = createCCMap(inMap);
				// サービスを呼び出す
				HashMap<String,Object> outputMap = invokeServiceCNSV0060(ccMap);
				// サービスの処理結果を判定
				String returnCode = outputMap.get("RETURN_CODE").toString();

				if (RETURN_CODE_SUCCESS.equals(returnCode)) {
					HashMap<String, Object> resultMap = (HashMap<String, Object>)outputMap.get("CNSV006001CC");
					String resultCode = resultMap.get(PARAM_RESULT_CD).toString();

					//リターンコードが正常の場合、コンテンツ事業クレジットカードへの更新を行う。
					if(AUTH_RESULT_AUTHOK.equals(resultCode))
					{
						// コンテンツ事業クレジットカード更新
						JBSbatCommonDBInterface dbList = new JBSbatCommonDBInterface();
						String flrlmtFirst = crecardCompInfo.get(JBSbatKK_M_CRECARD_COMP.FLRLMT_FIRST);		 // フロアリミット初回金額
						// UPDATEパラメータの設定
						dbList.setValue("");											// オーソリ結果区分
						dbList.setValue("");											// オーソリ確認年月日時分秒
						dbList.setValue("");											// オーソリ承認番号
						dbList.setValue(flrlmtFirst);									// フロアリミットチェック済金額
						dbList.setValue("");											// 決済ID
						dbList.setValue("");											// マーチャント取引ID
						dbList.setValue(inMap.getString(JBSbatCNIFM015.CRECARD_ID));	// クレジットカードID
						dbList.setValue(inMap.getString(JBSbatCNIFM015.CHRG_TRGT_YM));	// 課金対象年月

						// Update実行
						executeCN_T_CONTJIGYO_CRECA_CN_UPDATE_003(dbList.getList().toArray());
					} else {
						// API呼出しに対する、リターンコードが正常または警告以外であればNGファイルへ出力する
						outputInItem.addOutMapList(createNgData(inMap, resultMap, crecardCompNm));
					}
				} else {
					// エラーログ出力
					commonItem.getLogPrint().printBusinessErrorLog(JPCBatchMessageConstant.EKKB0270CE, 
							new String[]{"オーソリキャンセル(ペイジェント)"});
					// エラーフラグ設定
					super.commonItem.setErrFlg(true);
					throw new JBSbatBusinessError();

				}
			}

			super.logPrint.printDebugLog("execute_END");
		}
		return outputInItem;
		/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		db_KK_M_CRECARD_COMP.close();
		db_CN_T_CONTJIGYO_CRECA.close();
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
		/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}


	/**
	 * クレジットカード会社情報を取得します。
	 * 
	 * @return HashMap<String, Object> クレジットカード会社情報マップ
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private HashMap<String, Object> makeCrecardCompInfoMap() throws Exception
	{
		HashMap<String, Object>retMap = new HashMap<String, Object>();
		// 運用日付取得
		String strOpeDate = commonItem.getOpeDate();

		// クレジットカード会社よりデータを取得する。
		executeKK_M_CRECARD_COMP_CN_SELECT_004(strOpeDate);
		JBSbatCommonDBInterface crecardCompInfo = db_KK_M_CRECARD_COMP.selectNext();

		// 取得結果判定
		if (crecardCompInfo != null)
		{
			// 取得情報をマップに格納する
			while(null != crecardCompInfo)
			{
				HashMap<String, String> tmpInfo = new HashMap<String, String>();

				tmpInfo.put(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_CD, crecardCompInfo.getString(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_CD));
				tmpInfo.put(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_NM, crecardCompInfo.getString(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_NM));
				tmpInfo.put(JBSbatKK_M_CRECARD_COMP.FLRLMT_FIRST, crecardCompInfo.getString(JBSbatKK_M_CRECARD_COMP.FLRLMT_FIRST));
				retMap.put(crecardCompInfo.getString(JBSbatKK_M_CRECARD_COMP.CRECARD_COMP_CD), tmpInfo);
				crecardCompInfo = db_KK_M_CRECARD_COMP.selectNext();
			}
		}

		return retMap;
	}

	/**
	 * SQLKEY(CN_SELECT_004)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		 	運用日付
	 *		 	運用日付
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeKK_M_CRECARD_COMP_CN_SELECT_004(String strOpeDate) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(strOpeDate);	// 運用日付
		paramList.setValue(strOpeDate);	// 運用日付

		// DBアクセスを実行します
		db_KK_M_CRECARD_COMP.selectBySqlDefine(paramList, KK_M_CRECARD_COMP_CN_SELECT_004);
	}

	/**
	 * クレジットカード会社情報を取得します。。
	 * 
	 * @param crecardCompCd クレジットカード会社コード
	 * @return JBSbatCommonDBInterface クレジットカード会社情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	@SuppressWarnings("unchecked")
	private HashMap<String, String> selectCrecardCompInfo(String crecardCompCd) throws Exception
	{
		return (HashMap<String, String>) crecardCompInfoMap.get(crecardCompCd);
	}

	/**
	 * SQLKEY(CN_UPDATE_001)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	オーソリ結果区分
	 *		 	オーソリ確認年月日時分秒
	 *		 	オーソリ承認番号
	 *		 	フロアリミットチェック済金額
	 *		 	決済ID
	 *		 	マーチャント取引ID
	 *		 	クレジットカードID
	 *		 	課金対象年月
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeCN_T_CONTJIGYO_CRECA_CN_UPDATE_003(Object[] param) throws Exception
	{
		// 設定値のマップを作成します
		JBSbatCommonDBInterface setMap = new JBSbatCommonDBInterface();
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.AUTHORI_RSLT_DIV, param[0].toString());
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.AUTHORI_CFM_DTM, param[1].toString());
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.AUTHORI_SHONIN_NO, param[2].toString());
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.FLRLMT_CHK_ZUMI_AMNT, param[3].toString());
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.KSSAI_ID, param[4].toString());
		setMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.MERCHANT_DEAL_ID, param[5].toString());

		// 条件のマップを作成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.CRECARD_ID, param[6].toString());
		whereMap.setValue(JBSbatCN_T_CONTJIGYO_CRECA.CHRG_TRGT_YM, param[7].toString());

		// DBアクセスを実行します
		db_CN_T_CONTJIGYO_CRECA.updateByPrimaryKeys(whereMap, setMap);
	}

	/**
	 * キャンセル処理呼出しに失敗したエラー情報データを生成する
	 * <BR>
	 * @param inMap 売上オーソリ対象データ
	 * @param outputMap ペイジェントより返却された値
	 * @return outmap JBSbatServiceInterfaceMap
	 * @throws Exception 
	 * 
	 */
	private JBSbatServiceInterfaceMap createNgData(JBSbatServiceInterfaceMap inMap,
			HashMap<String,Object> outputMap,
			String crecardCompNm) throws Exception
			{
		// 入出力インターフェースオブジェクトを生成
		JBSbatServiceInterfaceMap outmap = new JBSbatServiceInterfaceMap();

		// データのインスタンスを生成
		outmap.setString(JBSbatCNLST01501.AUTHORI_ERR_DIV, PARAM_AuthoriErrorKbn_2);	// オーソリエラー区分
		outmap.setString(JBSbatCNLST01501.CRECARD_ID, inMap.getString(JBSbatCNIFM015.CRECARD_ID));	// クレジットカードID
		outmap.setString(JBSbatCNLST01501.SYSID, inMap.getString(JBSbatCNIFM015.SYSID));	// SYSID
		// 共通部品より年月書式(yyyy/MM)の編集を行う。
		String taisho_ym = JPCUtilCommon.formatYears(inMap.getString(JBSbatCNIFM015.CHRG_TRGT_YM));
		outmap.setString(JBSbatCNLST01501.CHRG_TRGT_YM, taisho_ym);	// 課金対象年月
		// 共通部品「文字列書式変換部品」の数値書式編集処理メソッドを呼び出す。
		Long seikyAmnt = inMap.getLong(JBSbatCNIFM015.SEIKY_AMNT);
		String amnt = JPCUtilCommon.formatNumber(seikyAmnt.toString());
		outmap.setString(JBSbatCNLST01501.CHRG_AMNT, amnt);	// 課金額
		outmap.setString(JBSbatCNLST01501.AZKR_ID, inMap.getString(JBSbatCNIFM015.CRECARD_NO));	// 預かりID
		// 共通部品より年月書式(yyyy/MM)の編集を行う。
		String yk_kigen = JPCUtilCommon.formatYears(inMap.getString(JBSbatCNIFM015.CRECARD_YK_KIGEN));
		outmap.setString(JBSbatCNLST01501.CRECARD_YK_KIGEN, yk_kigen);	// 有効期限
		outmap.setString(JBSbatCNLST01501.CREDIT_COMP_NM, crecardCompNm);	// クレジット会社名
		outmap.setString(JBSbatCNLST01501.MERCHANT_DEAL_ID, inMap.getString(JBSbatCNIFM015.MERCHANT_DEAL_ID));	// マーチャント取引ID
		outmap.setString(JBSbatCNLST01501.RESULT_CODE, outputMap.get(PARAM_RESULT_CD).toString());	// 処理結果コード
		outmap.setString(JBSbatCNLST01501.RESPONSE_CD, outputMap.get(PARAM_RESPONSE_CODE).toString());	// レスポンスコード
		outmap.setString(JBSbatCNLST01501.RESPONSE_DETAIL, outputMap.get(PARAM_RESPONSE_DETAIL).toString());	// レスポンス詳細

		//出力フラグを設定
		outmap.setOutFlg(true);

		// データを返却
		return outmap;
			}

	/**
	 * ＣＣ向けのマップを作成する。
	 * @param inMap 読み込みファイルの内容
	 */
	private HashMap<String, Object> createCCMap(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		HashMap<String, Object> ccMap = new HashMap<String, Object>();
		ccMap.put(PARAM_MERCHANT_DEAL_ID, inMap.getString(JBSbatCNIFM015.MERCHANT_DEAL_ID));	// マーチャント取引ID
		// v58.00.01 IT1-2022-0000040 MOD START
		//ccMap.put(PARAM_KSSAI_ID, inMap.getString(JBSbatCNIFM015.KSSAI_ID));					// 決済ID
		ccMap.put(PARAM_KSSAI_ID, JPCUtilCommon.trim(inMap.getString(JBSbatCNIFM015.KSSAI_ID)));// 決済ID
		// v58.00.01 IT1-2022-0000040 MOD END
		return ccMap;
	}

	/**
	 * サービス(CNSV0060)を呼び出す
	 * <br>
	 * @param ccMap
	 * @return
	 * @throws Exception 
	 */
	private HashMap<String, Object> invokeServiceCNSV0060(HashMap<String, Object> ccMap) 
	{

		HashMap<String, Object> paramMap = new HashMap<String, Object>();

		// オーソリキャンセル(ペイジェント)CC呼び出し
		paramMap.put(JCCBatchEsbInterface.TELEGRAM_INFO_USECASE_ID, USECASE_ID);
		paramMap.put(JCCBatchEsbInterface.TELEGRAM_INFO_OPERATION_ID, OPERATION_ID);

		// サービスに渡す業務データを格納するMAPです。
		HashMap<String, Object> inputMap = new HashMap<String, Object>();

		// inputMapにCCに必要な情報をセットする
		inputMap.put(CNSV006001CC, ccMap);

		// サービスの処理結果が格納されるMAPを生成
		HashMap<String, Object> outputMap = new HashMap<String, Object>();
		// サービスを呼び出す
		JCCBatchEsbInterface.invokeService(super.commonItem, paramMap, inputMap, outputMap);

		// 処理結果を返却する
		return outputMap;
	}

	/**
	 * メソッド名  ：null、空文字判定
	 * メソッド説明：nullもしくは空文字の判定を行う
	 * 備考：
	 * @param strCheck 対象文字列
	 * @return true :対象文字列がnullもしくは空文字
	 *          false:上記以外
	 */
	private static boolean isNullOrBlank(String strCheck) 
	{

		// 対象文字列が対象文字列がnullもしくは空文字の場合、trueを返す
		return strCheck == null || "".equals(strCheck);
	}
}
