/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatCKTCAFileSksi
*	ソースファイル名	：JBSbatCKTCAFileSksi.java
*	作成者				：富士通　
*	作成日				：2014年05月16日
*＜機能概要＞
*　TCA向けファイル作成処理です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v8.00.00	2014/05/16  FJ)江藤		新規作成(ANK-2023-00-00)
*	v8.00.01	2014/06/13  FJ)谷口		【OM-2014-0002159】連携ファイルの項目をダブルクォーテーションで括らないよう改修
*	v49.00.00	2020/05/31  FJ)星野		ANK-3807-00-00
*********************************************************************/
package eo.business.service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JKKBatCommon;
import eo.business.common.JKKBatConst;
import eo.business.util.file.JBSbatCKIFM003;
import eo.business.util.table.JBSbatZM_M_CD_NM_KANRI;
import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.file.JBSbatOutputFileUtil;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;

/**
* TCA向けファイル作成 <p>
*<BR>
* @author 富士通
*/
public class JBSbatCKTCAFileSksi extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/** テーブル(コード名称管理)*/
	private static final String D_TBL_NAME_ZM_M_CD_NM_KANRI = "ZM_M_CD_NM_KANRI";
	
	/** SQL定義キー(KK_SELECT_004)*/
	private static final String ZM_M_CD_NM_KANRI_KK_SELECT_004= "KK_SELECT_004";

	/** テーブルアクセスクラス(コード名称管理)*/
	private JBSbatSQLAccess db_ZM_M_CD_NM_KANRI = null;

	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** コード種別コード（事業者コード(TCA)） */
	private static final String CD_SBT_CD_JGS_CD_TCA = "CD01643";
	/** コード種別コード（自事業者コード(TCA)） */
	private static final String CD_SBT_CD_JI_JGS_CD_TCA  = "CD01644";

	/** アプリケーションプロパティ（バッチ） ＴＣＡ向けファイル送信ディレクトリ定義キー */
	private static final String CK_TCA_SEND_DIR_KEY = "CK_TCA_SEND_DIR";
	/** プロパティ値 ＴＣＡ向けファイル送信ディレクトリの区切り文字 */
	private static final String PROP_TCA_SEND_DIR_SEP = ",";
	/** プロパティ値 ＴＣＡ向けファイル送信ディレクトリの区切り文字（事業者コードとパスの区切り） */
	private static final String PROP_TCA_SEND_DIR_SEP_2 = ":";

	/** 出力ファイルの文字コード */
	private static final String ENCODE  = JKKBatConst.SJIS;
	/** 出力ファイルの改行コード */
	private static final String LINE  = "CR+LF";

	/** ダブルクォーテーション */
	public static final String DOUBLE_QUOT = "\"";

	/** ファイル出力制御オブジェクト（事業者ごとに管理） */
	private HashMap<String, JBSbatOutputFileUtil> sendFile = new HashMap<String, JBSbatOutputFileUtil>();

	/**
	 * 初期処理<br>
	 * 送信対象の事業者ごとに出力ファイルを作成します。
	 * <br>
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_ZM_M_CD_NM_KANRI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_ZM_M_CD_NM_KANRI);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/

		// 事業者コード(TCA)取得
		ArrayList<String> jgsCdTCAList = getJgsCdList(CD_SBT_CD_JGS_CD_TCA);

		// 自事業者コード(TCA)取得
		ArrayList<String> jiJgsCdTCAList = getJgsCdList(CD_SBT_CD_JI_JGS_CD_TCA);

		// 送信ディレクトリ情報取得
		HashMap<String, Object> sendDirInf = getSendDirInf();

		// 出力ファイル名取得
		String[] freeItem = this.freeItem.split(";");
		String dirPath = freeItem[0];
		String fileName = freeItem[1];

		for (String jgsCd : jgsCdTCAList)
		{
			// 自事業者コード(TCA)でない場合
			if (!jiJgsCdTCAList.contains(jgsCd))
			{
				if (null != sendDirInf.get(jgsCd))
				{
					
// ANK-3807-00-00対応 ADD START
					File f_outputDir = new File(dirPath + sendDirInf.get(jgsCd));
					// ディレクトリがなかったら作成
					if(!f_outputDir.isDirectory()){
						f_outputDir.mkdirs();
					}
// ANK-3807-00-00対応 ADD END
					// 出力ファイルを作成
					String outFileName = dirPath + sendDirInf.get(jgsCd) + fileName;
					JBSbatOutputFileUtil fileUtil = new JBSbatOutputFileUtil(outFileName);
					fileUtil.setEncode(ENCODE);
					fileUtil.setLine(LINE);
					fileUtil.createWriter();
					sendFile.put(jgsCd, fileUtil);
				}
				else
				{
					// 事業者コード(TCA)に予備の事業者コードがマスタに定義されているため、
					// ディレクトリの定義がない場合、処理なしとする
					
				}
			}
		}
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap 入力電文
	 * @param outputInItem 入力情報
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputInItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		// INPUTの読み込みが全て終了した時点で、メイン処理を実行する
		if(inMap == null)
		{
			// メイン処理
			JBSbatOutputItem outputItem = mainProp(outputInItem);

			return outputItem;
		}
		else
		{
			// INPUTの読み込みが全て終了していない場合
			// 退避レコード格納リストに、現レコードを保存して、処理を終了する
			outputInItem.addOutMapList(inMap);
			return outputInItem;
		}
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		db_ZM_M_CD_NM_KANRI.close();
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/

		// 出力ファイルのクローズ
		for (JBSbatOutputFileUtil fileUtil : sendFile.values())
		{
			if (null != fileUtil)
			{
				fileUtil.close();
			}
		}
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**
	 * SQLKEY(KK_SELECT_004)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	コード種別コード
	 *		 	コード適用開始年月日
	 *		 	コード適用終了年月日
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeZM_M_CD_NM_KANRI_KK_SELECT_004(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString());
		paramList.setValue(param[2].toString());

		// DBアクセスを実行します
		db_ZM_M_CD_NM_KANRI.selectBySqlDefine(paramList, ZM_M_CD_NM_KANRI_KK_SELECT_004);
	}
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	/**
	 * メイン処理<BR>
	 * @param outputInItem 入力情報
	 * @return JBSbatOutputItem 出力情報
	 * @throws Exception 例外が発生した場合
	 */
	private JBSbatOutputItem mainProp(JBSbatOutputItem outputInItem) throws Exception
	{
		// 戻り値の出力情報
		JBSbatOutputItem outputItem = new JBSbatOutputItem();

		for (Entry<String, JBSbatOutputFileUtil> sendFileEntry : sendFile.entrySet())
		{
			String jgsCd = sendFileEntry.getKey();
			JBSbatOutputFileUtil fileUtil = sendFileEntry.getValue();

			// TCA向けファイルを出力（出力に必要な情報は初期処理で取得済み）
			outPutTCAFile(outputInItem, jgsCd, fileUtil);
		}

		return outputItem;
	}

	/**
	 * TCA向けファイルを出力します。
	 * <br>
	 * @param outputInItem 入力情報
	 * @param jgsCd 事業者コード
	 * @param fileUtil ファイル出力制御オブジェクト
	 * @throws Exception 例外が発生した場合
	 */
	@SuppressWarnings("unchecked")
	private void outPutTCAFile(JBSbatOutputItem outputInItem, String jgsCd, JBSbatOutputFileUtil fileUtil) throws Exception
	{
		for (int i = 0; i < outputInItem.getOutMapList().size(); i++)
		{
			HashMap<String, Object> inMap = ((JBSbatServiceInterfaceMap)outputInItem.getOutMapList().get(i)).getMap();

			String[] colList = new String[]
			{
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_KANA),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_NM),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_BIRTHD),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_SEX_CD),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_PCD),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_AD_NM),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_AD_CD),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_TELNO),
				(String)inMap.get(JBSbatCKIFM003.HURYO_CUST_MOVE_TELNO),
				(String)inMap.get(JBSbatCKIFM003.SYSID),
				// 事業者コードは下4桁を送信先の事業者コードに書き換える
				((String)inMap.get(JBSbatCKIFM003.HURYO_CUST_JIGYOSHA_CD)).substring(4) + jgsCd,
				(String)inMap.get(JBSbatCKIFM003.NONPAY_AMNT),
			};

			// 1行出力
			String line = editCsv(colList);
			fileUtil.write(line);
		}
	}

	/**
	 * 項目リストをダブルクォーテーション囲みのカンマ区切りに編集して返します。
	 * <br>
	 * @param colList 項目リスト
	 * @return 編集結果
	 */
	private String editCsv(String[] colList)
	{
		StringBuilder sb = new StringBuilder();
	
		for (int i = 0; i < colList.length; i++)
		{
			// OM-2014-0002159 ダブルクォーテーションで括らないよう改修 CHANGE START
//			if (0 < i)
//			{
				sb.append(colList[i]);
				if (i != (colList.length -1))
				{
					sb.append(JKKBatConst.S_SEP_CAM);
				}
//			}
//			sb.append(DOUBLE_QUOT).append(colList[i]).append(DOUBLE_QUOT);
			// OM-2014-0002159 ダブルクォーテーションで括らないよう改修 CHANGE END
		}
	
		return sb.toString();
	}

	/**
	 * 事業者コードのリストを取得します。
	 * <br>
	 * @param cdSbtCd コード種別コード
	 * @return 事業者コードのリスト
	 * @throws Exception 例外が発生した場合
	 */
	private ArrayList<String> getJgsCdList(String cdSbtCd) throws Exception
	{
		ArrayList<String> jgsCdTcaList = new ArrayList<String>();

		ArrayList<HashMap<String, Object>> resultList = getCdNmKanri(cdSbtCd);
		if (null == resultList || resultList.isEmpty())
		{
			throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0520CE, 
					new String[]{"コード名称管理", "コード種別：" + cdSbtCd});
		}

		for (HashMap<String, Object> resultMap : resultList)
		{
			jgsCdTcaList.add((String)resultMap.get(JBSbatZM_M_CD_NM_KANRI.CD_DIV));
		}

		return jgsCdTcaList;
	}

	/**
	 * コード名称管理より該当のコード種別のコードを取得します。
	 * <br>
	 * @param cdSbtCd  コード種別コード
	 * @return 検索結果
	 * @throws Exception 例外が発生した場合
	 */
	@SuppressWarnings("unchecked")
	private ArrayList<HashMap<String, Object>> getCdNmKanri(String cdSbtCd) throws Exception
	{
		ArrayList<HashMap<String, Object>> resultList  = new ArrayList<HashMap<String, Object>>();
		
		Object[] prm = new Object[]{cdSbtCd, super.opeDate, super.opeDate};
		executeZM_M_CD_NM_KANRI_KK_SELECT_004(prm);
		
		// 取得したコード名称管理の内容をハッシュテーブルに格納する
		JBSbatCommonDBInterface dbInterface = db_ZM_M_CD_NM_KANRI.selectNext();
		while(dbInterface != null)
		{
			resultList.add((HashMap<String, Object>)dbInterface.getMap());
			dbInterface = db_ZM_M_CD_NM_KANRI.selectNext();
		}

		return resultList;
	}

	/**
	 * 送信ディレクトリ情報を取得します。
	 * <br>
	 * @return ディレクトリ情報（キー：事業者コード、値：パス）
	 * @throws Exception 例外が発生した場合
	 */
	private HashMap<String, Object> getSendDirInf() throws Exception
	{
		HashMap<String, Object> resultMap  = new HashMap<String, Object>();

		// プロパティファイルから「ＴＣＡ向けファイル送信ディレクトリ」を取得する
		String propValue = JKKBatCommon.getApplicationConst(CK_TCA_SEND_DIR_KEY);

		if (null == propValue || propValue.isEmpty())
		{
			// 該当キー無しのエラー
			throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0520CE, 
					new String[]{"プロパティファイル（バッチ）", "キー：" + CK_TCA_SEND_DIR_KEY});
		}

		// 「事業者コード：パス,事業者コード：パス,…」をMap形式に変換する
		String[] sendDirList = propValue.split(PROP_TCA_SEND_DIR_SEP);
		for (String sendDir : sendDirList)
		{
			String[] val = sendDir.split(PROP_TCA_SEND_DIR_SEP_2);
			resultMap.put(val[0], val[1]);
		}

		return resultMap;
	}

}
