/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatCHKssaidkCvsNkinInfoReq
*	ソースファイル名	：JBSbatCHKssaidkCvsNkinInfoReq.java
*	作成者				：富士通　
*	作成日				：2017年04月06日
*＜機能概要＞
*　決済代行会社コンビニ入金情報要求部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2017/04/06   富士通		新規作成
*	v32.00.00	2017/05/29	【ANK-2996-00-00】リクエストパラメータの設定不備
*	v32.00.01	2017/05/31	 FJ)西面   【ANK-2996-00-00】SMSを利用した即時決済
*	v32.00.02	2017/06/16	 FJ)西面   【ANK-2996-00-00】テストモード起動時のリクエスト制御
*********************************************************************/
package eo.business.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCCBatCommon;
import eo.business.common.JCHBatKssaidkHttps;
import eo.business.common.JCHBatKssaidkHttpsBase;
import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.util.JBSbatAplConst;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatCHKssaidkCvsNkinInfoReq extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/**バージョン */
	private static final String VERSION = "version";
	/**処理区分 */
	private static final String SHORIKBN = "shori_kbn";
	/**決済手段区分 */
	private static final String BILL_METHOD = "bill_method";
	/**契約コード */
	private static final String SHOP_CD = "shop_cd";
	/**収納企業コード */
	private static final String SHUNO_CO_CD = "syuno_co_cd";
	/**拠点コード */
	private static final String KYOTEN_CD = "kyoten_cd";
	/**拠点検索対象有無 */
	private static final String INC_KYOTEN_FLG = "inc_kyoten_flg";
	/**取引検索用ショップパスワード */
	private static final String SHOP_PWD = "shop_pwd";
	/**処理日 From */
	private static final String SHORI_DATE_FROM = "shori_date_from";
	/**処理時分 From */
	private static final String SHORI_TIME_FROM = "shori_time_from";
	/**処理日 To */
	private static final String SHORI_DATE_TO = "shori_date_to";
	/**処理時分 To */
	private static final String SHORI_TIME_TO = "shori_time_to";
	/**商品明細出力有無 */
	private static final String SHOHIN_MEISAI_FLG = "shohin_meisai_flg";
	/**レコード区分（ヘッダ） */
	private static final String RECORD_DIV_HEAD = "10";
	/**レコード区分（データ） */
	private static final String RECORD_DIV_DATA = "20";
	/**レコード区分（エンド） */
	private static final String RECORD_DIV_END = "80";
	/**結果コード（正常） */
	private static final String KEKKA_CD_1 = "000000";
	/**結果コード（条件に合致するデータが存在しません） */
	private static final String KEKKA_CD_2 = "943037";
	/** APLconst設定値 */
	private static final String APL_CH_SHOP_CD = "CH_SHOP_CD";
	/** APLconst設定値 */
	private static final String APL_CH_SHUNO_CO_CD = "CH_SHUNO_CO_CD";
	/** APLconst設定値 */
	private static final String APL_CH_KYOTEN_CD = "CH_KYOTEN_CD";
	/** APLconst設定値 */
	private static final String APL_CH_SHOP_PWD = "CH_SHOP_PWD";
	/** APLconst設定値 */
	private static final String APL_CH_SHORI_TIME_FROM = "CH_SHORI_TIME_FROM";
	/** APLconst設定値 */
	private static final String APL_CH_SHORI_TIME_TO = "CH_SHORI_TIME_TO";
	/** 退避．ヘッダ件数 */
	private int head_kensu = 0;
	/** 退避．データ件数 */
	private int data_kensu = 0;
	/** 退避．エンド件数 */
	private int end_kensu = 0;
	/** 退避．処理件数 */
	private String syori_kensu = null;
	/**拠点検索対象有無：有 */
//v32.00.00 2017/05/29 Del Start
//	private static final String INC_KYOTEN_FLG_ARI = "1";
//v32.00.00 2017/05/29 Del End

//v32.00.00 2017/05/29 Add Start
	private static final String INC_KYOTEN_FLG_NASHI = "0";
//v32.00.00 2017/05/29 Add End

//v32.00.02 2017/06/16 Add Start
	private static final String KSSAIDK_REQ_MODE_TEST = "1";
//v32.00.02 2017/06/16 Add End
	/**商品明細出力有無：無 */
	private static final String SHOHIN_MEISAI_FLG_NASHI = "0";
	/**HTTPステータス：OK */
	private static final String HTTP_OK = "200";

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		
//v32.00.02 2017/06/16 Add Start
		//テスト環境での呼出しか否かを判断する
		if(isTestMode())
		{
			//テストモードで起動された場合、擬似的に空ファイルを作成する
			makeFileEmpty();
			
			//後続の処理は行わず終了する
			return null;
		}
//v32.00.02 2017/06/16 Add End
		
		//リクエスト格納用Map作成
		HashMap<String, String> inmap = new HashMap<String, String>();
		
		//レスポンス格納用Map作成
		HashMap<String, ArrayList<String>> outmap = new HashMap<String,  ArrayList<String>>();
		
		//結果出力用
		ArrayList<String> outputlist = new ArrayList<String>();
		//リクエスト設定処理
		this.makereq(inmap);
		//----------------------------------------
		//連携モジュール呼び出し部分
		//----------------------------------------
		JCHBatKssaidkHttps api = new JCHBatKssaidkHttps();
		try
		{
			api.execute(commonItem, inmap, outmap);
		}
		catch(SocketTimeoutException e )
		{
			//メジャーエラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB1650CE);
		}
		//ステータスコード判定
		String statuscode = inmap.get(JCHBatKssaidkHttpsBase.EXE_STATUS);
		if (!HTTP_OK.equals(statuscode))
		{
			String[] msgParam = new String[]{ statuscode };
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB1660CE, msgParam);
		}
		//レスポンス取得用リスト作成
		 ArrayList<String> response = new  ArrayList<String>();
		 //レスポンス取得
		 response = outmap.get(JCHBatKssaidkHttpsBase.RESPONSE);
		 
		//整合性チェックを行う。
		this.responsechk(response, outputlist);
		//ファイル出力処理
		this.makefile(outputlist);
		
		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * ファイル出力処理
	 * @param outputlist 
	 * @return 
	 * @throws IOException 
	 * @throws JBSbatBusinessException 
	 * @throws IOException 
	 */
	private void makefile(ArrayList<String> outputlist) throws JBSbatBusinessException, IOException {
		
//v32.00.01 2017/05/30 Add Start
		FileOutputStream fos = new FileOutputStream(super.freeItem);
		OutputStreamWriter osw = new OutputStreamWriter(fos,"SJIS");
//v32.00.01 2017/05/30 Add end
		
		BufferedWriter bw = null;
		try
		{
//v32.00.01 2017/05/30 Mod Start
//			 bw = new BufferedWriter(new FileWriter(super.freeItem));
			 bw = new BufferedWriter(osw);
//v32.00.01 2017/05/30 Mod End

			for(int i = 0 ; i < outputlist.size() ; i ++) {
	
				String line = outputlist.get(i);
			
				bw.write(line);
				bw.newLine();
			}
			bw.flush();
			bw.close();
		}
		catch(IOException e)
		{
			// ファイルの作成に失敗
			String rsn = "ファイルの作成に失敗（";
			StringBuffer buf = new StringBuffer();
			buf.append("ファイルパス：");
			buf.append(super.freeItem);	
			buf.append("）");
			// エラーを投げる
			throw new JBSbatBusinessException("ECHB1550CE", new String[]{ rsn, buf.toString() });
		}
		finally
		{
			bw.close();
		}
	}

	/**
	 * 整合性チェック処理
	 * @param response 
	 * @param outputlist 
	 * @return 
	 * @throws Exception 
	 * @paramHashMap<String, String> inmap
	 * @throws Exception
	 */
	
	private void responsechk(ArrayList<String> response, ArrayList<String> outputlist) throws Exception {

		//レコード並び順確認用配列初期化
		ArrayList<String> recordList = new ArrayList<String>();
		//レコード区分確認処理
		this.recorddivchk(response, recordList, outputlist);
		//レコード区分並び順確認
		this.recorddivorderchk(recordList);
		
		//件数チェック
		if (!Integer.toString(data_kensu).equals(syori_kensu) )
		{
			//レコード総件数エラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB1290AE);
		}
		
	}

	/**
	 * レコード区分並び順確認処理
	 * @return 
	 * @param recordList
	 * @throws JBSbatBusinessException 
	 */
	private void recorddivorderchk(ArrayList<String> recordList) throws JBSbatBusinessException {
		
		//ヘッダ件数が1件出ない場合
		if (head_kensu != 1)
		{
			//レコード区分並び順エラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB0500AE);
		}
		//レコード区分確認用配列：0番目要素が"10"（ヘッダ）出ない場合
		if (!recordList.get(0).equals(RECORD_DIV_HEAD))
		{
			//レコード区分並び順エラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB0500AE);
		}
		//エンド件数が1件出ない場合
		if (end_kensu != 1)
		{
			//レコード区分並び順エラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB0500AE);
		}
		//レコード区分確認用配列：最後の要素が"80"（エンド）出ない場合
		if (!recordList.get(recordList.size() - 1).equals(RECORD_DIV_END))
		{
			//レコード区分並び順エラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB0500AE);
		}
	}

	/**
	 * レコード区分確認処理
	 * @param response 
	 * @return 
	 * @param recordList
	 * @param outputlist
	 * @throws JBSbatBusinessException 
	 * @throws IOException 
	 * @throws Exception
	 */
	private void recorddivchk(ArrayList<String> response, ArrayList<String> recordList,
			ArrayList<String> outputlist) throws JBSbatBusinessException, IOException 
	{
		String str = null;
		//結果コード
		String kekka_cd = null;
		
		for(int i = 0; i < response.size(); i++)
		{
	
				//ファイル出力用に退避
				outputlist.add(response.get(i));
				//ダブルクォーテーションの削除
				str = response.get(i).replaceAll("\"", "");
//				//カンマで区切ります。
				String[] column = str.split(",");
				//レコード区分を取得
				String record_div_res = column[0];
				
				//レコード区分がヘッダ、データ、エンドでない場合
				if (!RECORD_DIV_HEAD.equals(record_div_res) && !RECORD_DIV_DATA.equals(record_div_res) && !RECORD_DIV_END.equals(record_div_res) )
				{
					//レコード区分エラー
					throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB0490AE);
				}
				//配列[0]要素="10"(ヘッダ）の場合
				if (RECORD_DIV_HEAD.equals(record_div_res))
				{
					//結果コードを設定
					kekka_cd = column[1];
					//結果コードが正常出ない場合
					if (!KEKKA_CD_1.equals(kekka_cd) && !KEKKA_CD_2.equals(kekka_cd))
					{
						// 異常終了
						String[] msgParam = new String[]{ "CHIFE523", kekka_cd };
						throw new JBSbatBusinessException(JPCBatchMessageConstant.ECHB1570CE, msgParam);
					}
					//ヘッダ件数カウントアップ
					head_kensu = head_kensu + 1;
				}
				//データ部の場合
				if (RECORD_DIV_DATA.equals(record_div_res))
				{
					//件数カウントアップ
					data_kensu = data_kensu + 1;
				}
				//エンド部の場合
				if (RECORD_DIV_END.equals(record_div_res))
				{
					//処理件数取得
					syori_kensu = column[1];
					//エンド件数カウントアップ
					end_kensu = end_kensu + 1;
				}
				recordList.add(record_div_res);
		}
	}

	/**
	 * リクエスト設定処理
	 * @return 
	 * @paramHashMap<String, String> inmap
	 * @throws Exception
	 */
	private void makereq(HashMap<String, String> inmap) {
		
		//バージョン（"213"（データ連携（自動連携照会）））
		inmap.put(VERSION, "213");
		//処理区分（"1800"（入金処理日時情報））
		inmap.put(SHORIKBN, "1800");
		//決済手段区分（"03"（コンビニエンスストア（受付番号）））
		inmap.put(BILL_METHOD, "03");
		//契約コード
		inmap.put(SHOP_CD, JBSbatAplConst.getAplConstValue(APL_CH_SHOP_CD));
		//収納企業コード
		inmap.put(SHUNO_CO_CD, JBSbatAplConst.getAplConstValue(APL_CH_SHUNO_CO_CD));	
//v32.00.00 2017/05/30 Del Start
		//拠点コード
//		inmap.put(KYOTEN_CD, JBSbatAplConst.getAplConstValue(APL_CH_KYOTEN_CD));
//v32.00.00 2017/05/30 Del End
		//拠点検索対象有無（"1"（含む））
//v32.00.00 2017/05/29 Mod Start
//		inmap.put(INC_KYOTEN_FLG, INC_KYOTEN_FLG_ARI);
		inmap.put(INC_KYOTEN_FLG, INC_KYOTEN_FLG_NASHI);
//v32.00.00 2017/05/29 Mod End
		//取引検索用ショップパスワード
		inmap.put(SHOP_PWD, JBSbatAplConst.getAplConstValue(APL_CH_SHOP_PWD));
		//処理日 From（バッチ運用日（日中）前日）
		inmap.put(SHORI_DATE_FROM, JCCBatCommon.addDay(super.opeDate, -1));
		//処理時分 From（"2001"）
		inmap.put(SHORI_TIME_FROM, JBSbatAplConst.getAplConstValue(APL_CH_SHORI_TIME_FROM));
		//処理日 To（バッチ運用日（日中））
		inmap.put(SHORI_DATE_TO, super.opeDate);
		//処理時分 To ("2000"）
		inmap.put(SHORI_TIME_TO, JBSbatAplConst.getAplConstValue(APL_CH_SHORI_TIME_TO));
		//商品明細出力有無（"0"（出力しない））
		inmap.put(SHOHIN_MEISAI_FLG, SHOHIN_MEISAI_FLG_NASHI);
		
	}
	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

//v32.00.02 2017/06/16 Add Start
	/**
	 * 擬似ファイルを作成する
	 * テストモードで呼出した場合、外部システム（決済ステーション）への接続は行わないため
	 * 後続の処理へ連携するファイルとして擬似的にファイルを作成する
	 * @throws IOException 
	 * @throws IOException 
	 * @throws JBSbatBusinessException
	 * @throws IOException
	 */
	private void makeFileEmpty() throws IOException {
		
		//ファイルの読込処理を実行するを行う
		FileOutputStream fos = new FileOutputStream(super.freeItem);
		//ファイルの形式をSJISに指定する
		OutputStreamWriter osw = new OutputStreamWriter(fos, "SJIS");

		BufferedWriter bw = new BufferedWriter(osw);

		/**----------------------------------------------------------------------
		 *  後続処理へ擬似ファイルを作成するため、外部システム（決済ステーション）
		 *  に接続した結果取得件数が0件だった場合を想定して作成する
		 *  イメージ（年月日には運用日を設定する）
		 *  "10","000000","正常","20200801000000"
		 *  "80","0"
		 * ----------------------------------------------------------------------*/
		
		//ヘッダレコードを作製する
		bw.write("\"10\",\"000000\",\"正常\",\"");
		bw.write(super.opeDate.toString());
		bw.write("000000\"");
		
		//次レコードへ
		bw.newLine();
		
		//エンドレコードの作製を行う
		bw.write("\"80\",\"0\"");

		bw.flush();
		bw.close();
		
	}
	
	/**
	 * APLConstからテストモード用のフラグを取得し
	 * テストモードか否かの判断を行う
	 * @return true テストモード false 本番モード
	 */
	private boolean isTestMode ()
	{
		
		//APLConstより、決済代行会社リクエストモードを取得する
		String reqMode = JCCBatCommon.getApplicationConst("CH_KSSAIDAIKO_REQ_MODE_FLG");
		
		//リクエストモードがテスト用だった場合true（テストモード）を返却する
		if(KSSAIDK_REQ_MODE_TEST.equals(reqMode))
		{
			return true;
		}
		
		//上記以外はfalse(本番モード）を返却する
		
		return false;
	}
//v32.00.02 2017/06/16 Add End

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
}
